谈发布订阅模式和观察者模式
背景
设计模式不是软件开发的专业术语。事实上,“模式”最早诞生于建筑学。
设计模式被定义为面向对象软件设计过程中对特定问题的简单而优雅的解决方案。一般来说,设计模式在某些情况下是一个问题的解决方案。更通俗地说,设计模式就是在面向对象的软件开发中命名一些好的设计。
这些“好的设计”不是任何人发明的,而是已经存在于软件开发中。稍有经验的程序员可能已经不知不觉中使用了这些设计模式几次。GOF(四人帮,《设计模式》作者)最大的成就是从浩瀚的面向对象世界中挑选出这些“好设计”,并给它们起了一个好听又令人难忘的名字。
设计模式不是直接用来完成代码编写的,而是描述如何在不同情况下解决问题的方案。它不是一种死机制,而是一种思想和一种编写代码的形式。每种语言对于不同的设计模式都有自己的实现,这在某些语言中可能不适用于某些设计模式,例如javascript的工厂方法模式。模式应该用在正确的地方。而什么是正确的,只有在我们深刻理解模型的意图后,结合项目的实际场景才会知道。
模范社区一直在发展。GoF在1995年提出了23种设计模式,但模式并不局限于这23种,后来增加到了24种。在过去的20年里,也许有更多的模式被发现和总结。例如,一些JavaScript书籍提到了模块模式和沙盒模式。这些“模式”能否被世界认可并传承下来,还有待时间的验证。
观察者模式(观察者模式)
观察者模式定义了对象之间的一对多依赖关系。当一个对象的状态改变时,所有依赖它的对象都会被通知并自动更新。观察者模式属于行为模式,侧重于物体之间的交流,观察者模式是观察者与被观察者之间的交流。
观察者模式有一个不同的名字,即“发布-订阅模式”,或“订阅-发布模式”。订户和订阅目标链接在一起。当订阅目标改变时,会逐一通知订阅者。我们可以用报刊的订阅来形象地说明,当你订阅一份报纸时,每天都会有最新的报纸送到你面前,报纸会发出和订阅它的人一样多的报纸。报纸和订阅报纸的客户是上面文章开头提到的“一对多”依赖关系。
发布-订阅模式(发布-订阅模式)
事实上,在24种基本设计模式中没有发布-订阅模式。如上所述,它只是观察者模式的另一个名称。
但经过时间的沉淀,似乎他变得强大了,独立于观察者的格局,而变成了一个不同的设计格局。
在当前的发布-订阅模式下,称为发布者的消息发送者不会将消息直接发送给订阅者,这意味着发布者和订阅者不知道彼此的存在。发布者和订阅者之间有第三个组件,称为消息代理或调度中心或中间件,它维护发布者和订阅者之间的联系,过滤来自发布者的所有传入消息,并相应地将它们分发到订阅者。
比如你在微博上关注A,还有很多人关注A,那么当A发布消息的时候,微博就会为你推送这个消息。a是发布者,你是订阅者,微博是调度中心。你和A之间没有直接的消息交流,都是通过微博协调的(你关心的,A的发布动态)。
观察者模式和发布订阅模式有什么区别?
我们先来看看这两种模式的实现结构:
观察者模式:观察者直接订阅主体,当主体被激活时,会触发观察者内的事件。
发布-订阅模式:订阅者将自己想要订阅的事件订阅到调度中心(Topic),当发布者将事件发布到调度中心时,即事件触发时,调度中心统一将订阅者注册的处理代码调度到调度中心。
让我们看看这两种模式的代码案例:(猎人发布和订阅任务)
观察者模式:
//有猎人工会,每个猎人都有发布和订阅的功能。//他们都有订阅列表,记录谁订阅了自己。//定义猎人类。//包括名称、级别、订阅列表函数Hunter(名称、级别){ this . name=name this . level=level this . list=[]} Hunter . prototype . publish=function(money){ console . log(this . level ' Hunter ' this . name '请求帮助)this . list . foreach(function(item,index){ item(money)} } Hunter . prototype . subscribe=function(targrt,Fn){ console . log(this . level ' Hunter ' this . name '订阅' targrt . name)list。让亨特明=新猎人('小明',金')让亨特金=新猎人('小金','银')让亨特张=新猎人('张晓','金')让猎人彼得=新猎人('彼得','青铜')//彼得等级低,可能需要帮助。因此,小明、小金、张晓均认缴彼得亨特明。subscribe (Hunter Peter),function (money) {console.log('小明说:'(money 200?“:”暂时比较忙,没办法’)‘帮’)})猎人金。订阅(Hunter Peter,function () {console.log('小金说:help')}) Hunter Zhang。Subscribe (Hunter Peter,Function(){ console.log('小张说:help') }) //Peter遇到困难,赏金198向Hunter Peter . publish(198)//Hunter(观察者)关联他们感兴趣的猎人(目标对象),比如Peter,当Peter遇到困难时,他会自动通知他们(观察者)发布订阅:
//定义一个猎人工会//主要功能包括话题发布大厅,以及订阅、发布让猎人工会={type :' hunt ',话题:对象。create (null),subscribe 3360函数(topic,fn) {if(!this . topics[topic]){ this . topics[topic]=[];} this.topics[topic]。push(fn);},publish:函数(话题,金钱){ if(!this.topics[topic])返回;对于(让fn这个。topics[topic]){ fn(money)} } }//定义了一个猎人类//包括名字、等级函数Hunter(name,Level) {this。name=namethis。level=level }//猎人可以发布订阅任务猎人。原型。subscribe=function (topic,Fn){ console . log(this . level ' Hunter ' this . name '订阅了狩猎' topic '的任务)HunterUnion.subscribe(topic,Fn)} Hunter . prototype . publish=function(topic,Money){ console . log(this . level ' Hunter ' this . name '发布了狩猎' topic '的任务)HunterUnion.publish(topic,Money)} //有一些猎人来自猎人联盟。让亨特明=新猎人(“小明”,“金”)让亨特金=新猎人(“小金”,“银”)让亨特张=新猎人(“小张”,“金”)让亨特彼得=新猎人(“彼得”,“青铜”)//小明,金枭和小张分别订阅了亨特明。subscribe ('tiger ',function (money) {console.log '(小明说:“(money 200?【否】)【接任务】)})猎人金。subscribe ('tiger ',Function(money){ console . log(' Xiaojin '意为:接任务')}) hunterZhang.subscribe('tiger ',Function(money){ console . log(' Xiaozhang '表示:接任务')}) //Peter订阅了hunterPeter.subscribe('羊',Function(money){ console . log(' Peter '表示:接任务')}) //Peter发布了猎虎任务,猎人Peter。publish ('tiger ',198)//猎人的发布(publisher)或订阅(observer/subscriber)任务都是通过猎人工会(调度中心)进行关联的,它们之间的区别观察者模式和发布-订阅模式最大的区别就是发布-订阅模式有一个事件调度中心。
观察者模式是由特定目标调度的,每个订阅的目标都需要处理观察者,这种方式简单粗暴,但会造成代码冗余。
在发布订阅模式下,调度中心统一处理,订阅者和发布者互不干扰,消除了发布者和订阅者之间的依赖关系。一方面实现解耦,另一方面可以实现一些更细粒度的控制。例如,发布者发布了大量消息,但不希望所有订阅者都收到这些消息,因此他们可以在调度中心进行一些处理,类似于权限控制。您还可以执行一些节流操作。
观察者模式是发布-订阅模式吗
网上对这个问题的回答两极分化。有人认为发布-订阅模式是观察者模式,也有人认为观察者模式和发布-订阅模式真的不一样。
其实我不知道发布-订阅模式是不是观察者模式,正如我不知道区分模式的关键是设计意图还是设计结构(idea),虽然《JavaScript设计模式与开发实践》说区分模式的关键是意图而不是结构。
如果按结构区分模式,发布-订阅模式比观察者模式多一个中间件订阅者,所以发布-订阅模式不同于观察者模式如果按意图区分模式,它们都实现了对象之间的一对多依赖关系。当一个对象的状态改变时,所有依赖它的对象都会得到通知并自动更新,然后它们就是相同的模式,发布-订阅模式会根据观察者模式进行优化和升级。
然而,不管它们是否是相同的设计模式,它们的实现方法确实是不同的。使用时要根据场景判断选择哪一个。
以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。
版权声明:谈发布订阅模式和观察者模式是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。