原文連接: 觀察者模式再次進階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