今天复习vue双向绑定原理时,一时半会想不起,发布订阅模式跟观察者模式的区别。下面写了个小demo记录一下。
发布订阅模式
class Event {
constructor () {
this.listeners = {}
}
on(key, listener) {
if (!this.listeners[key]) {
this.listeners[key] = []
}
this.listeners[key].push(listener)
}
emit(key, data) {
const keyListener = this.listeners[key];
if (keyListener) {
keyListener.forEach(cb => {
cb(data)
});
}
}
}
const event = new Event();
event.on('hi', function(data) {
console.log('hi, this is '+data+' event!');
})
event.emit('hi', 'lyc')
// 输出结果:hi, this is lyc event!
观察者模式
class Subject {
constructor() {
this.observers = []
}
add(observer) {
this.observers.push(observer)
}
notify() {
this.observers.forEach(observer => {
observer.update();
})
}
}
class Observer {
constructor(name) {
this.name = name;
}
update() {
console.log('观察者'+ this.name+ '被通知了');
}
}
const sub = new Subject();
const ob1 = new Observer('lyc');
const ob2 = new Observer('lzj');
sub.add(ob1);
sub.add(ob2);
sub.notify();
// 输出结果:
// 观察者lyc被通知了
// 观察者lzj被通知了
区别
角色角度
- 发布订阅模式需要三种角色,发布者、事件中心和订阅者。
- 观察者模式需要两种角色,目标和观察者,无事件中心负责通信。
耦合角度
- 发布订阅模式是一个事件中心调度模式,订阅者和发布者是没有直接关联的,通过事件中心进行关联,两者是解耦的。
- 观察者模式中目标和观察者是直接关联的,耦合在一起
事件角度
- 发布订阅可以维护多个事件(主题)及依赖各事件(主题)的对象之间的关系;
- 观察者模式维护单一事件对应多个依赖该事件的对象关系;目标对象直接触发通知(全部通知),观察对象被迫接收通知。
优缺点
发布订阅模式
优点:
-
灵活
由于订阅发布模式的发布者和订阅者是解耦的,只要引入订阅发布模式的事件中心,无论在何处都可以发布订阅。同时订阅发布者相互之间不影响。
缺点:
-
容易导致代码不好维护
灵活是优点,同时也是缺点,使用不当就会造成数据流混乱,导致代码不好维护。
-
性能消耗更大
订阅发布模式需要维护事件列队,订阅的事件越多,内存消耗越大。
观察者模式
优点:
-
响应式
目标变化就会通知观察者,这是观察者最大的优点,也是因为这个优点,观察者模式在前端才会这么出名。
缺点:
-
不灵活
相比订阅发布模式,由于目标和观察者是耦合在一起的,所以观察者模式需要同时引入目标和观察者才能达到响应式的效果。而订阅发布模式只需要引入事件中心,订阅者和发布者可以不再一处。