前言
观察者模式和发布订阅模式是两种设计模式,可以基于多种设计模式设计架构模式。
观察者模式
观察者模式有两个角色,观察者 & 被观察者。
例子1:拍卖师报价。拍卖师就是被观察者,观众和竞拍者就是观察者。
例子2:报纸期刊的订阅。报社就是被观察者,订报的人就是观察者
观察者模式定义了一种一对多的情况,当这个一发生变化,这些多都会得到通知
// 被观察者
class Dep {
constructor() {
this.watchers = [] // 观察者列表,通知的时候要用
}
// 添加观察者
addWatcher(watcher) {
this.watchers.push(watcher)
}
// 通知所有观察者
notify() {
this.watchers.forEach(watcher => {
watcher.update()
})
}
}
// 观察者
class Watcher {
constructor(callback) {
this.callback = callback
}
update() {
this.callback()
}
}
// 创建被观察者
const dep = new Dep()
// 创建观察者 1,2
const watcher1 = new Watcher(() => console.log('1'))
const watcher2 = new Watcher(() => console.log('2'))
// 将观察者加入到被观察者上
dep.addWatcher(watcher1)
dep.addWatcher(watcher2)
// 要发新通知了
dep.notify()
setTimeout(() => {
dep.notify()
}, 2000)
当观察者加入监听之后就会接收到被观察者发出的通知。代码形式可以变化,并不一定要按照上面的方式
✅ 整理出观察者和被观察者的逻辑,进行解耦
❌ 所有的观察者都收到信息,不能自定义
发布订阅模式
发布订阅模式有三个角色,发布者 & 订阅者 & 事件中心。例子:网友通过淘宝买东西。网友是订阅者,商家是发布者,物流则是事件中心
将每个订阅者独立看待,把订阅者的回调函数放置到事件中心存放。
class PubSub {
constructor() {
this.list = []
}
// 订阅
subscribe(key, fn) {
this.list.push({
key,
fn
})
}
// 发布
publish(key) {
for (let i = 0; i < this.list.length; i++) {
if (key === this.list[i].key) {
this.list[i].fn()
break
}
}
}
// 取消订阅
unSubscribe() { }
}
const pub = new PubSub()
pub.subscribe('s1', () => {
console.log('s1')
})
pub.subscribe('s2', () => {
console.log('s2')
})
pub.publish('s2')
setTimeout(() => {
pub.publish('s1')
}, 2000)
可以自定义发布订阅者
小结
- 观察者模式是一个目标对多个观察者,当目标发生改变,通知所有的观察者
- 发布订阅模式基于观察者模式上添加了事件中心做调度作用。可以自定义发布订阅者
- 两种模式都是抽离观察者和被观察者做到解耦的目的