大家好,如果您还对beego开发网站源码分享不太了解,没有关系,今天就由本站为大家分享beego开发网站源码分享的知识,包括基于beego框架开源项目 流程系统的问题都会给大家分析到,还望可以解决大家的问题,下面我们就开始吧!
终于写完了创建型和结构型设计模式(共12个),现在开始写行为型设计模式(共11个)。观察者模式的应用场景非常广泛,小到代码层面的解耦,大到架构层面的系统解耦,再或者一些产品的设计思路,都有这种模式的影子。
UML类图位置:https://www.processon.com/view/link/60d29bf3e401fd49502afd25
本文代码链接为:https://github.com/shidawuhen/asap/blob/master/controller/design/18observer.go
1.定义
1.1观察者模式
观察者模式:观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己。
UML:
1.2分析
观察者模式算是比较通用的设计模式了,思路也比较清晰。Subject里有Observer集合,当Subject有更新时,通知各个Observer。Subject为了管理Observer,自身设置了增加、删除功能。
当Subject有更新,通知Observer时,有很多细节值得讨论。
第一个问题是使用同步阻塞还是异步非阻塞
同步阻塞是最经典的实现方式,主要是为了代码解耦;异步非阻塞除了能实现代码解耦之外,还能提高代码的执行效率;
第二个问题是如何保证所有Observer都通知成功。
方案一是利用消息队列ACK的能力,Observer订阅消息队列。Subject只需要确保信息通知给消息队列即可。方案二是Subject将失败的通知记录,方便后面进行重试。方案三是定义好规范,例如只对网络失败这种错误进行记录,业务失败类型不管理,由业务自行保证成功。
第三个问题是不同进程/系统如何进行通知。
进程间的观察者模式解耦更加彻底,一般是基于消息队列来实现,用来实现不同进程间的被观察者和观察者之间的交互。
2.使用场景
观察者模式的使用场景还是很多的,它和享元模式一样,更多体现的是一种设计理念。
记得前些日子遇到一个场景,正好使用的是观察者模式。商家购买服务的订单,有多个状态,如交易成功、交易取消、开始履约等。业务场景只关注交易成功、交易取消和开始履约。如果不使用观察者模式,可以用if-else解决这个问题。但各个状态的处理逻辑比较复杂,而且状态有可能存在乱序的情况,导致要处理的case更多了。这时候用观察者模式就很合适,订单状态变更为Subject,具体处理逻辑为Observer,状态变更时,通知所有处理逻辑,谁合适处理便由谁处理。不但隔离性变好,扩展性也增强了。
3.代码实现
packagemain\nimport&34;\ntypePurchaseOperFuncfunc(statusstring,datastring)(resbool,errerror)\n/**\n*@Author:JasonPang\n*@Description:注册的观察者\n*/\nvarPurchaseOperFuncArr=[]PurchaseOperFunc{\ncreate,\nisDeleted,\napply,\n}\n/**\n*@Author:JasonPang\n*@Description:用于创建的观察者\n*@paramstatus\n*@paramdata\n*@returnres\n*@returnerr\n*/\nfunccreate(statusstring,datastring)(resbool,errerror){\nifstatus==&34;{\nfmt.Println(&34;)\nreturntrue,nil\n}\nreturntrue,nil\n}\n/**\n*@Author:JasonPang\n*@Description:用于删除的观察者\n*@paramstatus\n*@paramdata\n*@returnres\n*@returnerr\n*/\nfuncisDeleted(statusstring,datastring)(resbool,errerror){\nifstatus==&34;{\nfmt.Println(&34;)\nreturntrue,nil\n}\nreturntrue,nil\n}\n/**\n*@Author:JasonPang\n*@Description:用于履约的观察者\n*@paramstatus\n*@paramdata\n*@returnres\n*@returnerr\n*/\nfuncapply(statusstring,datastring)(resbool,errerror){\nifstatus==&34;{\nfmt.Println(&34;)\nreturntrue,nil\n}\nreturntrue,nil\n}\nfuncmain(){\nstatus:=&34;\ndata:=&34;\n//有状态更新时,通知所有观察者\nfor_,oper:=rangePurchaseOperFuncArr{\nres,err:=oper(status,data)\niferr!=nil{\nfmt.Println(&34;)\nbreak\n}\nifres==false{\nfmt.Println(&34;)\nbreak\n}\n}\n}\n
输出:
?myprojectgorunmain.go
开始创建
这个代码是个简单版,但整体逻辑是一样的。这种写法的好处有如下几个:
如果要处理新的状态,则实现后再PurchaseOperFuncArr添加即可,改动不大根据具体业务来说,只能有一个逻辑是真正负责执行的,所以有一个错误就报错,然后重试即可。不过具体逻辑需要做好幂等
总结
实际上,设计模式要干的事情就是解耦。创建型模式是将创建和使用代码解耦,结构型模式是将不同功能代码解耦,行为型模式是将不同的行为代码解耦,具体到观察者模式,它是将观察者和被观察者代码解耦。
最后
大家如果喜欢我的文章,可以关注我的公众号(程序员麻辣烫)
我的个人博客为:https://shidawuhen.github.io/
往期文章回顾:
招聘
字节跳动|内推大放送字节跳动|今日头条广州服务端研发工程师内推字节跳动|抖音电商急招上海前端开发工程字节跳动|抖音电商上海资深服务端开发工程师-交易字节跳动|抖音电商武汉服务端(高级)开发工程师字节跳动|飞书大客户产品经理内推咯字节跳动|抖音电商服务端技术岗位虚位以待字节跳动招聘专题
设计模式
Go设计模式(17)-享元模式Go设计模式(16)-组合模式Go设计模式(15)-门面模式Go设计模式(14)-适配器模式Go设计模式(13)-装饰器模式Go设计模式(12)-桥接模式Go设计模式(11)-代理模式Go设计模式(10)-原型模式Go设计模式(9)-建造者模式Go设计模式(8)-抽象工厂Go设计模式(7)-工厂模式Go设计模式(6)-单例模式Go设计模式(5)-类图符号表示法Go设计模式(4)-代码编写优化Go设计模式(4)-代码编写Go设计模式(3)-设计原则Go设计模式(2)-面向对象分析与设计Go设计模式(1)-语法
语言
再也不怕获取不到Gin请求数据了一文搞懂pprofGo工具之generateGo单例实现方案Go通道实现原理Go定时器实现原理Beego框架使用Golang源码BUG追查Gin框架简洁版Gin源码剖析
架构
分页复选设计的坑支付接入常规问题限流实现2秒杀系统分布式系统与一致性协议微服务之服务框架和注册中心浅谈微服务限流实现1CDN请求过程详解常用缓存技巧如何高效对接第三方支付算法总结
存储
一文搞懂MySQL数据库分库分表MySQL开发规范Redis实现分布式锁事务原子性、一致性、持久性的实现原理InnoDB锁与事务简析
网络
HTTP2.0基础教程HTTPS配置实战HTTPS连接过程TCP性能优化
工具
GoLand实用技巧根据mysql表自动生成gostructMarkdown编辑器推荐-typora
读书笔记
《毛选》推荐原则资治通鉴敏捷革命如何锻炼自己的记忆力简单的逻辑学-读后感热风-读后感论语-读后感孙子兵法-读后感
思考
对过去的一点回顾对写博客的一些思考晚上打119的经历为动员一切力量争取胜利而斗争反对自由主义实践论评价自己的标准2020博客总结服务端团队假期值班方案项目流程管理对项目管理的一些看法对产品经理的一些思考关于程序员职业发展的思考关于代码review的思考
OK,本文到此结束,希望对大家有所帮助。
