兩個模式的實現結構: 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