發佈/訂閱者模式

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

相關文章
相關標籤/搜索