最近,再重学 JavaScript 知识,对于观察者模式与发布订阅模式有了更深层次的了解,这也就是我们所说的“温故而知新”,今天我们来看看它们之间有哪些区别。
观察者模式
当对象之间存在一对多的依赖关系时,当被观察的对象状态发生改变时,所有观察它的对象都会收到通知,这就是观察者模式。
基本思想
在观察者模式中,只有两种主体:目标对象 (Subject
) 和 观察者 (Observer
)。
在观察者模式中,Subject 对象拥有添加、删除和通知一系列 Observer 的方法等,而 Observer 对象拥有 update 更新方法等。在 Subject 对象添加了一系列 Observer 对象之后,Subject 对象则维持着这一系列 Observer 对象,当有关状态发生变更时 Subject 对象则会通知这一系列 Observer 对象进行更新。
优点
- 耦合度高,通常用来实现一些响应式的效果;
- 角色很明确,没有事件调度中心作为中间者,目标对象
Subject
和观察者Observer
都要实现约定的成员方法; - 双方联系紧密,目标对象的主动性很强,自己收集和维护观察者,并在状态变化时主动通知观察者更新;
实现
// 目标对象 class Subject { constructor() { this.observers = [] } add (observer) { this.observers.push(observer) } notify() { this.observers.map(observer => { if (observer && typeof observer.update === 'function') { observer.update() } }) } remove(observer) { const idx = this.observers.findIndex(itm => itm === observer) if (idx !== -1) { this.observers.splice(idx, 1) } } } // 观察者 class Observer { constructor(name) { this.name = name } update() { console.log(`${this.name} updated`) } } const subject = new Subject() const o1 = new Observer('Nina') const o2 = new Observer('Jack') subject.add(o1) subject.add(o2) console.log('第一次通知:') subject.notify() subject.remove(o1) console.log('删除 Nina 后,再次通知:') subject.notify()
打印结果为:
二者区别
- 概念与实现上
- 从概念上理解,两者没什么不同,都在解决对象之间解耦,通过事件的方式在某个时间点进行触发,监听这个事件的订阅者可以进行相应的操作。
- 在实现上有所不同,观察者模式对订阅事件的订阅者通过发布者自身来维护,后续的一些列操作都要通过发布者完成。发布订阅模式是订阅者和发布者中间会有一个事件总线,操作都要经过事件总线完成。
- 耦合
- 观察者模式是面向目标和观察者编程的,用于耦合目标和观察者。观察者和被观察者之间还存在耦合,被观察者还是知道观察者的;
- 发布 – 订阅模式是面向调度中心编程的,用于解耦发布者和订阅者。发布者和订阅者不需要知道对方的存在,通过消息代理进行通信,解耦更加彻底;
- 关系
- 观察者模式的观察者和被观察者就像 商家-顾客 的关系,当商品有更新等,商家会直接通知订阅的顾客。
- 发布订阅模式的发布者和订阅者,就像 商家-APP-顾客 的关系,顾客(订阅者)在 APP 上订阅商品通知,待商品有更新时,商家(发布者)通过 APP 通知订阅的顾客(订阅者)。
- 从使用层面上讲
- 观察者模式,多用于单个应用内部;
- 发布订阅模式,更多的是一种跨应用的模式(cross-application pattern),比如消息中间件;
结语
以上就是 javascript 中关于观察者模式与发布订阅模式区别,一点小小的学习总结,希望对大家有用。