发布订阅模式与观察者模式

https://blog.csdn.net/hf872914334/article/details/88899326

如有帮助,请感谢CSDN作者!!!

很清晰的讲解了二者之间的本质区别,并用代码清晰的完成实现过程。

背景

设计模式并非软件开发的术语,实际上“模式”最早诞生于建筑学。

设计模式的定义是:在面向对象软件设计过程中针对特定问题的简洁而优雅的解决方案。通俗一点说,设计模式是在某种场合下对某个问题的一种解决方案。如果再通俗一点说,设计模式就是给面向对象软件开发中的一些好的设计取个名字。

这些“好的设计”并不是谁发明的,而是早已存在于软件开发中。一个稍有经验的程序员也许在不知不觉中数次使用过这些设计模式。GoF(Gang of Four,《设计模式》几位作者)最大的功绩是吧这些好的设计从浩瀚的面向对象世界中挑选出来并给予它们一个好听又好记的名字。

设计模式并不直接用来完成代码的编写,而是描述在各种不同情况下,要怎么解决问题的一种方案,它不是一个死的机制,它是一种思想,一种写代码的形式。每种语言对于各种设计模式都有它们自己的实现方式,对于某些设计模式来说,可能在某些语言下并不适用,模式应该用在正确的地方。

观察者模式(Observe Pattern)

观察者模式定义了对象间的一种一对多的依赖关系。当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知,并自动更新。观察者模式属于行为型模式,行为型模式关注的是对象之间的通信,观察者模式就是观察者和被观察者之间的通信。

观察者模式有一个别名叫“发布-订阅模式”,或者说是“订阅-发布模式”,订阅者和订阅目标是联系在一起的,当订阅目标发生改变时,逐个通知订阅者,我们可以用报纸期刊的订阅来形象的说明,当你订阅了一份报纸,每天都会有一份最新的报纸送到你手上,有多少人订阅报纸,报社就会发多少份报纸,报社和订阅报纸的客户就是上面所说的“一对多”的依赖关系。

发布订阅模式(Pub-Sub Pattern)

它只是观察者模式的一个别称。

但是经过时间的沉淀,似乎它已经强大起来了,已经独立于观察者模式,成为另外一种不同的设计模式。

在现在的发布订阅模式中,称为发布者的消息发送者不会将消息直接发送给订阅者,这意味着发布者和订阅者不知道彼此的存在。在发布者和订阅者之间存在第三个组件,称为消息代理或调度中心或中间件,它维持着发布者和订阅者之间的联系,过滤所有发布者传入的消息并相应的分发它们给订阅者。

eg:你在微博关注了A,同时其他很多人也关注了A,那么当A发布动态的时候,微博就会为你们推送这条动态,A就是发布者,你就是订阅者,微博就是调度中心,你和A没有直接的消息往来,全部是微博来协调的。

观察者模式&发布订阅模式的区别

 

观察者模式:观察者(observe)直接订阅(subscribe)主题(subject),而当主题被激活的时候,会触发观察者里的事件。

发布订阅模式:订阅者(subscriber)把自己想订阅的事件注册到调度中心。当发布者(publish)发布该事件到订阅中心,也就是该事件触发时,由调度中心统一调度订阅者注册到调度中心的处理代码。

代码实现

观察者模式

function Hunter(name){
    this.name = name
    this.list = []
}
Hunter.prototype.publish = function(...args){
    this.list.forEach((fn)=>{
        fn.apply(this,args)
    })
}
Hunter.prototype.subscribe = function(target,fn){
    target.list.push(fn)
}
let hunterMing = new Hunter('小明')
let hunterPeter = new Hunter('Peter')
hunterMing.subscribe(hunterPeter,function(){
    console.log('给予帮助')
})
hunterPeter.publish()
class ObserverModel{
    constructor(name){
        this.name = name
        this.list = []
    }
}
ObserverModel.prototype.publish = function(...args){
    this.list.forEach(fn => {
        fn.apply(this,args)
    })
}
ObserverModel.prototype.subscribe = function(target,fn){
    target.list.push(fn)
}
let zjy = new ObserverModel('zjy')
let lyn = new ObserverModel('lyn')
lyn.subscribe(zjy,(args) => {
    console.log(`I get ${zjy.name} say,he ${args}`)
})
zjy.publish('need help')

发布订阅模式

https://www.cnblogs.com/zhenjianyu/p/12965006.html(代码实现部分为中间件订阅器部分)

观察者模式和发布订阅模式的最大区别就是发布订阅模式有个事件调度中心。

观察者模式由具体目标调度,每个被订阅的目标里面都需要有对观察者的处理,这种处理方式直接粗暴,但是会造成代码冗余。

发布订阅模式中统一由调度中心进行处理,订阅者和发布者互不干扰,消除了发布者和订阅者之间的依赖。这一方面实现了解耦,还有就是可以实现更细粒度的一些控制。比如发布者发布了很多消息,但是不想所有的订阅者都接收到,就可以在调度中心做一些处理。

观察者模式是不是发布订阅模式

网上关于这个问题的回答,出现了两极分化。有的认为发布订阅模式就是观察者模式,也有的认为观察者模式和发布订阅模式是真不一样。

其实我不知道发布订阅模式是不是观察者模式,就像我不知道辨别模式的关键是设计意图还是设计结构(理念),虽然《JavaScript设计模式与开发实践》中说分辨模式的关键是意图而不是结构。

如果以结构来分辨模式,发布订阅模式相比观察者模式多了一个中间件订阅器,所以发布订阅模式是不同于观察者模式的,如果以意图来分辨模式,它们都是实现了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知,并自动更新,那么它们就是同一种模式,发布订阅模式是在观察者模式的基础上做的优化升级。

posted @ 2020-08-21 15:04  671_MrSix  阅读(348)  评论(0编辑  收藏  举报