观察者设计模式
观察者模式是一种软件设计模式。在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实时事件处理系统。
简单来说就是,一个对象(被观察者)的状态发生改变时,会通知所有依赖它的对象(观察者),这两者是直接关联的。
如图所示,当Subject(被观察者)状态发生变化时,会给所有的Observers(观察者们)发送一个通知函数,观察者们接收到通知后通常会调用各自的更新函数。
发布-订阅设计模式
订阅发布模式是一种消息范式。消息的发送者(发布者)不会将消息直接发送给特定的接收者(订阅者)。而是将发布的消息分为不同的类别,无需了解哪些订阅者可能存在。同样的,订阅者可以表达对一个或多个类别的兴趣,只接收感兴趣的消息,无需了解哪些发布者存在。
在发布-订阅模式中,消息的发送方叫做发布者(publishers),消息不会直接发送给特定的接收者,叫做订阅者。
发布者和订阅者不知道对方的存在。需要一个第三方组件,叫做信息中介,它将订阅者和发布者串联起来,它过滤和分配所有输入的消息。
发布-订阅模式用来处理不同系统组件的信息交流,即使这些组件不知道对方的存在。
如上图所示,发布者与订阅者之间不是互相依赖和关联的,两者之间有一个通信结构(事件通道)。这个事件通道会处理发布者发布的不同类型的通知,并且将这些通知发送给相应的订阅者。
两者的区别
图片来源: developers-club
总结如下:
- 在观察者模式中,观察者是知道Subject的,Subject一直保持对观察者进行记录。然而,在发布订阅模式中,发布者和订阅者不知道对方的存在。它们只能通过消息代理进行通信。
- 在发布订阅模式中,组件是松散耦合的,正好和观察者模式相反。
- 观察者模式大多数时候是同步的,比如当事件触发,Subject就会去调用观察者的方法。而发布-订阅模式大多数时候是一步的(使用消息队列)
- 观察者模式需要在单个应用程序地址空间中实现,而发布-订阅更像交叉应用模式。
以下内容来自github项目【前端100问】下的讨论:
1.发布-订阅模式就好像报社,邮局和个人的关系,报纸的订阅和分发是由邮局来完成的。报社只负责将报纸发送给邮局。
2.观察者模式就好像个体奶农和个人的关系。奶农负责统计有多少人订了产品,所以个人都会有一个相同拿牛奶的方法。奶农有新奶了就负责调用这个方法。
观察者模式没有中间商赚差价
发布订阅模式有中间商赚差价
观察者模式为一刀切模式,对所有订阅者一视同仁
发布订阅模式可以戴有色眼镜,有一层过滤或者说暗箱操作
观察者模式就像mvvm,m的变化v可以感知而对应的做出变化
订阅发布模式就像mvc,m的变化必须依靠c来控制通知view,model有变化,view才能做出相应的改变。
参考文章:
https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/25