观察者模式
观察者模式定义了对象之间的一对多依赖。当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。而观察者模式属于行为型模式,行为型模式关注的是对象之间的通讯,观察者模式就是观察者和被观察者之间的通讯。
模式角色
- subject角色(主题): 它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者对象的方法
- Observer角色(观察者): 包含一个更新自己的方法,当接受到具体主题的更改通知时被调用
优点
- 降低主题与观察者之间的耦合关系,两者之间是松耦合关系
- 主题与观察者之间建立了一套触发机制
缺点
- 主题与观察者之间的依赖关系并没有完全解除
- 当观察者很多时,通知的发布会花费很多时间,影响效率
伪代码
function Subject(observers){
this.observers = observers ? [...observers]: [];
}
Subject.prototype.add = function(observer) {
this.observers.push(observer)
}
Subject.prototype.remove = function(observer){
// 移除对应的观察者
this.ovservers = this.observers.filter(item => item.id !== observer.id);
}
Subject.prototype.notify = function() {
this.observers.map(item => {
item.response()
})
}
function Obverser() {
// TODO
}
Obverser.prototype.response = function(arg) {
console.log('观察者被通知...')
}
发布订阅模式
模式角色
- publisher(发布者):发布消息(并不会直接通知订阅者)
- broker(经纪人):作为发布者和订阅者的中间层,接受消息,通知具体的订阅消息者
- subscriber(订阅者):订阅消息
优点
- 发布者和订阅者完全解耦
伪代码
以事件驱动为例
function Events() {
this.handles = {}
}
// 事件注册(订阅)
Events.prototype.on = function(eventName, callback){
if(!this.handles[eventName]) {
this.handles[eventName]= []
}
this.handles[eventName].push(callback)
}
// 事件触发(发布)
Events.prototype.emit = function(eventName,arg) {
if(this.handles[eventName]){
this.handles[eventName].map(fn => {
fn.call(this,arg)
})
}
}
var evt = new Events()
// 监听run事件
evt.on('run', res => {
console.log('run res:', res);
})
// 事件发布
evt.emit('run', 10)
观察者模式和发布订阅模式的区别
- 观察者模式只有两个角色(观察者和被观察者),而发布订阅模式除了发布者和订阅者之外还有经纪人
- 观察者和被观察者是松耦合关系,但发布者和订阅者完全解耦
- 观察者模式多用于单个应用内部。发布订阅模式更多的是跨应用的模式,比如消息中间件
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。