觀察者模式 與 發佈訂閱模式

兩個模式的實現結構: segmentfault

觀察者模式:觀察者(Observer)直接訂閱(Subscribe)主題(Subject),而當主題被激活的時候,會觸發(Fire Event)觀察者裏的事件。bash

觀察者模式定義了對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時,全部依賴於它的對象都將獲得通知,並自動更新。觀察者模式屬於行爲型模式,行爲型模式關注的是對象之間的通信,觀察者模式就是觀察者和被觀察者之間的通信。ui

發佈訂閱模式:訂閱者(Subscriber)把本身想訂閱的事件註冊(Subscribe)到調度中心(Topic),當發佈者(Publisher)發佈該事件(Publish topic)到調度中心,也就是該事件觸發時,由調度中心統一調度(Fire Event)訂閱者註冊到調度中心的處理代碼。this

發佈訂閱模式中,稱爲發佈者的消息發送者不會將消息直接發送給訂閱者,這意味着發佈者和訂閱者不知道彼此的存在。在發佈者和訂閱者之間存在第三個組件,稱爲消息代理或調度中心或中間件,它維持着發佈者和訂閱者之間的聯繫,過濾全部發布者傳入的消息並相應地分發它們給訂閱者。spa

代碼案例:(獵人發佈與訂閱任務)prototype

觀察者模式:代理

//有一家獵人工會,其中每一個獵人都具備發佈任務(publish),訂閱任務(subscribe)的功能
//他們都有一個訂閱列表來記錄誰訂閱了本身
//定義一個獵人類
//包括姓名,級別,訂閱列表
function Hunter(name, level){
    this.name = name
    this.level = level
    this.list = []
}
Hunter.prototype.publish = function (money){
    console.log(this.level + '獵人' + this.name+ '尋求幫助')
    this.list.forEach(function(item, index){
        item(money)
    })
}
Hunter.prototype.subscribe = function (targrt, fn){
    console.log(this.level + '獵人' + this.name + '訂閱了' + targrt.name)
    targrt.list.push(fn)
}

//獵人工會走來了幾個獵人
let hunterMing = new Hunter('小明', '黃金')
let hunterJin = new Hunter('小金', '白銀')
let hunterZhang = new Hunter('小張', '黃金')
let hunterPeter = new Hunter('Peter', '青銅')

//Peter等級較低,可能須要幫助,因此小明,小金,小張都訂閱了Peter
hunterMing.subscribe(hunterPeter, function(money){
    console.log('小明表示:' + (money > 200 ? '' : '暫時很忙,不能') + '給予幫助')
})
hunterJin.subscribe(hunterPeter, function(){
    console.log('小金表示:給予幫助')
})
hunterZhang.subscribe(hunterPeter, function(){
    console.log('小張表示:給予幫助')
})

//Peter遇到困難,賞金198尋求幫助
hunterPeter.publish(198)
複製代碼

發佈訂閱模式:code

//定義一家獵人工會
//主要功能包括任務發佈大廳(topics),以及訂閱任務(subscribe),發佈任務(publish)
let HunterUnion = {
    type: 'hunt',
    topics: Object.create(null),
    subscribe: function (topic, fn){
        if(!this.topics[topic]){
              this.topics[topic] = [];
          }
        this.topics[topic].push(fn);
    },
    publish: function (topic, money){
        if(!this.topics[topic])
              return;
        for(let fn of this.topics[topic]){
            fn(money)
        }
    }
}
function Hunter(name, level){
    this.name = name
    this.level = level
    this.list = []
}
Hunter.prototype.subscribe = function (topic, fn){
    console.log(this.level + '獵人' + this.name + '訂閱了狩獵' + topic + '的任務')
    HunterUnion.subscribe(topic, fn)
}
Hunter.prototype.publish = function (topic, money){
	console.log(this.level + '獵人' + this.name + '發佈了狩獵' + topic + '的任務')
	HunterUnion.publish(topic, money)
}
//獵人工會走來了幾個獵人
let hunterMing = new Hunter('小明', '黃金')
let hunterJin = new Hunter('小金', '白銀')
let hunterZhang = new Hunter('小張', '黃金')
let hunterPeter = new Hunter('Peter', '青銅')

//Peter等級較低,可能須要幫助,因此小明,小金,小張都訂閱了Peter
hunterMing.subscribe('tiger', function(money){
    console.log('小明表示:' + (money > 200 ? '' : '不') + '接取任務')
})
hunterJin.subscribe('tiger', function(){
    console.log('小金表示:接取任務')
})
hunterZhang.subscribe('tiger', function(){
    console.log('小張表示:接取任務')
})
hunterPeter.subscribe('sheep', function(){
    console.log('Peter表示:接取任務')
})

//Peter發佈了狩獵tiger的任務
hunterPeter.publish('tiger', 198)
//獵人們發佈(發佈者)或訂閱(觀察者/訂閱者)任務都是經過獵人工會(調度中心)關聯起來的,他們沒有直接的交流。
複製代碼

Sourcecdn

相關文章
相關標籤/搜索