观察者和发布订阅区别
二者所需的角色数量有着明显的区别。观察者模式本身只需要2个角色便可成型,即观察者和被观察者,其中被观察者是重点。而发布订阅需要至少3个角色来组成,包括发布者、订阅者和发布订阅中心,其中发布订阅中心是重点。
| 观察者模式 | 发布订阅 |
|---|---|
| 2个角色 | 3个角色 |
| 重点是被观察者 | 重点是发布订阅中心 |
观察者模式
观察者模式一般至少有一个可被观察的对象 Subject ,可以有多个观察者去观察这个对象。二者的关系是通过被观察者主动建立的,被观察者至少要有三个方法——添加观察者、移除观察者、通知观察者。
当被观察者将某个观察者添加到自己的观察者列表后,观察者与被观察者的关联就建立起来了。此后只要被观察者在某种时机触发通知观察者方法时,观察者即可接收到来自被观察者的消息
1. 被观察者实现
class Subject {
constructor(){
this.observerList = []
}
addObserver(observer){
this.observerList.push(observer)
}
removeObserver(observer){
const targetObserverIndex = this.observerList.findIndex(item => item.name === observer.name)
this.observerList.splice(targetObserverIndex, 1)
}
notifyObserver(msg = ''){
this.observerList.forEach(observer => observer.notified(msg))
}
}
2. 观察者实现
class Observer {
constructor(name){
// name主要用于在被观察者中删除观察者时,区分不同的观察者
this.name = name
}
notified(msg){
// do something
console.log(msg)
}
}
3. 使用
const observer1 = new Observer("observer1")
const observer2 = new Observer("observer2")
const subject = new Subject()
subject.addObserver(observer1)
subject.addObserver(observer2)
subject.notifyObserver()
发布订阅
与观察者模式相比,发布订阅核心基于一个中心来建立整个体系。其中发布者和订阅者不直接进行通信,而是发布者将要发布的消息交由中心管理,订阅者也是根据自己的情况,按需订阅中心中的消息。所以发布订阅需要3种角色——发布订阅管理中心、发布者、订阅者
1. 发布订阅管理中心实现
class PubCenter{
constrcutor(){
this.events = {}
}
subscribe(type, cb){
if(!this.events[type]){
this.events[type] = []
}
this.events[type].push(cb)
}
publish(type){
if(!this.events[type]){
this.events[type] = []
}
}
notified(type){
this.events[type]?.forEach(cb => cb())
}
}
2. 发布者实现
class Publisher{
constructor(pubCenter){
this.pubCenter = pubCenter
}
publish(type){
this.pubCenter.publish(type)
}
}
3. 订阅者中心
class Subscribe {
constructor(pubCenter){
this.pubCenter = pubCenter
}
subscribe(type, cb){
this.pubCenter.subscribe(type, cb)
}
}