這兩個模式很容易弄混,很容易讓人以爲這兩個模式是相同的。可是首先咱們要知道的是,這兩個模式是不一樣的。硬要說相同的話,那也是廣義上的相同(後面下文解釋)。咱們先來各自看看這兩種模式,最後再搞清楚這二者間的聯繫與區別。設計模式
是軟件設計模式的一種。在此種模式中,一個目標對象管理全部相依於它的觀察者對象,而且在它自己的狀態改變時主動發出通知。這一般透過呼叫各觀察者所提供的方法來實現。此種模式一般被用來實時事件處理系統。bash
簡單來講,觀察者模式就是,一個對象(被觀察者)的狀態發生改變時,會通知全部依賴它的對象(觀察者),這二者是直接關聯的。函數
如圖所示,當Subject(被觀察對象)狀態發生變化時,會給 全部的Observers(觀察者們)發送一個通知函數,觀察者們接收到通知後一般會調用各自的更新函數。咱們去餐廳吃飯的時候,常常會遇到須要排隊的時候。咱們能夠把餐廳看做時被觀察者,把排隊的客人(拿號排隊)看做是觀察者。當餐廳有位置的時候,餐廳會出來通知排隊的客人,到100號桌吃飯啦。這時排隊的客人們都會看看本身手上的號,肯定是否到本身吃飯了。學習
const Subject = (() => {
const observers = [];
const addOb = (ob) => {
observers.push(ob);
};
const notify = () => {
for (let ob of observers) {
if (typeof ob.update === 'function') {
ob.update();
}
}
};
return {addOb, notify};
})();
let subA = {
update: () => {
console.log('updateSubA');
}
},
subB = {
update: () => {
console.log('updateSubB');
}
};
Subject.addOb(subA); //添加觀察者subA
Subject.addOb(subB); //添加觀察者subB
Subject.notify(); //通知全部觀察者
複製代碼
是一種消息範式,消息的發送者(稱爲發佈者)不會將消息直接發送給特定的接收者(稱爲訂閱者)。而是將發佈的消息分爲不一樣的類別,無需瞭解哪些訂閱者(若是有的話)可能存在。一樣的,訂閱者能夠表達對一個或多個類別的興趣,只接收感興趣的消息,無需瞭解哪些發佈者(若是有的話)存在。ui
發佈者狀態更新時,發佈某些類型的通知,只通知訂閱了相關類型的訂閱者。發佈者和訂閱者之間是沒有直接關聯的。spa
如上圖所示,發佈者與訂閱者直接不是互相依賴和關聯的,二者之間有一個通訊結構(事件通道)。這個事件通道會處理髮布者發佈的不一樣類型的通知,而且將這些通知發送給相應的訂閱者。仍是以餐廳排隊吃飯爲例。此次咱們拿了號後,再也不傻傻地在餐廳門口等待。咱們掃了一下排隊二維碼,咱們在排隊的過程當中就能夠去幹其餘事情了,由於到咱們的號時,餐廳會發送一個通知給咱們。設計
const PubSub = (() => {
const topics = {}; //保存訂閱主題
const subscribe = (type, fn) => { //訂閱某類型主題
if (!topics[type]) {
topics[type] = [];
}
topics[type].push(fn);
};
const publish = (type, ...args) => { //發佈某類型主題
if (!topics[type]) {
return;
}
for (let fn of topics[type]) { //通知相關主題訂閱者
fn(args);
}
};
return {subscribe, publish};
})();
let subA = {type: 'event1'},
subB = {type: 'event2'},
subC = {type: 'event1'};
PubSub.subscribe(subA.type, () => console.log(`update eventType: ${subA.type} subA`)); //訂閱者A訂閱topic1
PubSub.subscribe(subB.type, () => console.log(`update eventType: ${subB.type} subB`)); //訂閱者B訂閱topic2
PubSub.subscribe(subC.type, () => console.log(`update eventType: ${subC.type} subC`)); //訂閱者C訂閱topic1
PubSub.publish(subA.type); //發佈topic通知,通知訂閱者A、C
複製代碼
廣義上來講,觀察者模式和發佈-訂閱模式,都是一個對象的狀態發生變化,通知相關聯的對象。因此廣義上來講,這兩種模式是類似的,正如《Head First設計模式》所說。code
發佈 + 訂閱 = 觀察者模式cdn
圖片來源:MSDNserver
本文旨在互相學習,本文屬我的理解,有說的不對的地方,師請糾正。轉載請註明原帖。