以前一直对观察者模式和发布订阅模式的区别理解不深,正好这段时间在看vue源码的分析,vue数据双向绑定也用到了发布订阅模式,因而又把这二者探究了一番,今天作个笔记增强印象。
观察者模式和发布订阅模式最大的区别就是发布订阅模式有个事件调度中心。vue
pubSub.pngthis
从图中能够看出,观察者模式中观察者和目标直接进行交互,而发布订阅模式中统一由调度中心进行处理,订阅者和发布者互不干扰。这样一方面实现了解耦,还有就是能够实现更细粒度的一些控制。好比发布者发布了不少消息,可是不想全部的订阅者都接收到,就能够在调度中心作一些处理,相似于权限控制之类的。还能够作一些节流操做。prototype
接下来看一下代码实现
观察者模式:双向绑定
// 观察者 class Observer { constructor() { } update(val) { } } // 观察者列表 class ObserverList { constructor() { this.observerList = [] } add(observer) { return this.observerList.push(observer); } remove(observer) { this.observerList = this.observerList.filter(ob => ob !== observer); } count() { return this.observerList.length; } get(index) { return this.observerList(index); } } // 目标 class Subject { constructor() { this.observers = new ObserverList(); } addObserver(observer) { this.observers.add(observer); } removeObserver(observer) { this.observers.remove(observer); } notify(...args) { let obCount = this.observers.count(); for (let index = 0; index < obCount; index++) { this.observers.get(i).update(...args); } } }
发布订阅模式:code
class PubSub { constructor() { this.subscribers = {} } subscribe(type, fn) { if (Object.prototype.hasOwnProperty.call(this.subscribers, type)) { this.subscribers[type] = []; } this.subscribers[type].push(fn); } unsubscribe(type, fn) { let listeners = this.subscribers[type]; if (!listeners || !listeners.length) return; this.subscribers[type] = listeners.filter(v => v !== fn); } publish(type, ...args) { let listeners = this.subscribers[type]; if (!listeners || !listeners.length) return; listeners.forEach(fn => fn(...args)); } } let ob = new PubSub(); ob.subscribe('add', (val) => console.log(val)); ob.publish('add', 1);
从上面代码能够看出,观察者模式由具体目标调度,每一个被订阅的目标里面都须要有对观察者的处理,会形成代码的冗余。而发布订阅模式则统一由调度中心处理,消除了发布者和订阅者之间的依赖。server
观察者模式跟咱们平时用的事件也有必定的关系,好比:事件
ele.addEventListener('click', () => {});
addEventListener就至关于注册了一个观察者,当观察到‘click’事件的时候,做出一些处理。rem
好啦,内容基本就这些,若是有什么不对的地方,欢迎指正哦~get