原文连接: 观察者模式再次进阶git
提及观察者模式, 每每会牵扯到发布/订阅模式. 二者存在着不少的类似之处, 它们都是维护着一个列表, 而后均可以对列表的对象进行增删和通知. 不一样的地方可能就在于处理添加和通知的方式上吧.github
发布/订阅模式使用了一个主题/事件通道, 这个通道介于但愿接到通知的对象(订阅者)和激活事件的对象(发布者)之间. 该事件系统容许代码定义应用程序的特定事件, 这些事件能够传达自定义参数, 自定义参数包含订阅者所需的值. 其目的是避免订阅者和发布者之间产生依赖关系. ———《设计模式: 可复用面向对象软件基础》
如下全部代码参见publish/subscribe.
既然和观察者模式相似, 那么在从观察者模式提及提到的小故事, 就能够接着往下续了.
subject1带着那么一拨人回去复命, 通过一段时间的磨合实践, 效果也是很明显. 附近的公司听到风声后, 也纷纷组织派遣员工前来学习. 人多了, 需求也变多了, 这么多人确定不能再呆在一块儿学习了. 原来只是一个公司的人呆在一间屋子里学习, 获得命令后你们开始各司其职. 如今, 各个公司的学习内容不一样, 它们理应独立开来. 由于各个公司动做能够不一样步, 但公司内部必定要同步起来. 为了区别对待, 每一个公司都有能和别人区分的令牌, 有了令牌同一个公司的人就能够进入与令牌相对应的房间了(固然一我的也能够有不少令牌, 商业间谍吧😂).设计模式
// 我是Pubsub, 我负责管理这拨人. class Pubsub { constructor() { // 维护事件列表, 这里将以对象的形式出现, key: value, key: 令牌, value: 同一公司员工列表. this. handles = {} } }
如今, 不一样公司的人前来学习的时候, 须要告诉Pubsub他们公司的令牌号, 进而引领到令牌对应的房间.app
class Pubsub { // 省略 // 注册事件. 若是是公司第一次派人过来, 那就新开一间. subscribe(type, handle) { if (!this.handles[type]) { this.handles[type] = [] } this.handles[type].push(handle) } }
若是某个房间的某我的, 或整个房间的人都不打算来了, 也须要Pubsub将其注销.函数
class Pubsub { // 省略 // 注销事件. 公司我的或总体注销. unsubscribe(type, handle) { let pos = this.handles[type].indexOf(handle) if (!handle) { // 不传handle, 则默认注销全部和type事件相关的事件处理函数. this.handles.length = 0 } else { ~pos && this.handles[type].splice(pos, 1) } } }
不一样的团体作出了区分, 算是万事具有. 想要哪一个房间里的人动起来, 有了令牌号, 只要对着吼一嗓子便可.学习
class Pubsub { // 省略 // 通知事件 publish() { // 执行全部和type事件相关的处理函数. let type = Array.prototype.shift.call(arguments) this.handles[type].forEach(handle => { // 箭头函数不绑定Arguments对象 handle.apply(this, arguments) }) } }
让咱们看看效果如何.this
let handle1 = (...rest) => { document.write('handle1', JSON.stringify(rest), '<br/>') } let handle2 = (...rest) => { document.write('handle2', JSON.stringify(rest)) } let ps = new Pubsub() ps.subscribe('notify-1', handle1) ps.subscribe('notify-1', handle2) ps.subscribe('notify-2', handle2) ps.unsubscribe('notify-1', handle2) ps.publish('notify-1', 'hahaha', 'heiheihei', [], {}) ps.publish('notify-2', 'hehehehehe') // 结果: handle1["hahaha","heiheihei",[],{}] handle2["hehehehehe"]
不难发现, 咱们的Pubsub老师只认令牌😅.prototype