最近被人問到設計模式,觀察者(observer)模式和發布(publish)/訂閱(subscribe)模式二者有什麼區別。其實這兩種模式還是有些許差異的,本質上的區別是排程的方式不同。
觀察者模式,目標和觀察者是基類,目標提供維護觀察者的一系列方法,觀察者提供更新介面。具體觀察者和具體目標繼承各自的基類,然後具體觀察者把自己註冊到具體目標裡,在具體目標發生變化時候,排程觀察者的更新方法。
比如有個「天氣中心」的具體目標a,專門監聽天氣變化,而有個顯示天氣的介面的觀察者b,b就把自己註冊到a裡,當a觸發天氣變化,就排程b的更新方法,並帶上自己的上下文。
示例
// 觀察者列表
function observerlist ()
observerlist.prototype.add = function (obj)
observerlist.prototype.count = function ()
observerlist.prototype.get = function (index)
}observerlist.prototype.indexof = function (obj, startindex)
i++;
}return -1;
}observerlist.prototype.removeat = function (index)
// 目標
function subject ()
subject.prototype.addobsever = function (observer)
subject.prototype.removeobsever = function (observer)
subject.prototype.notify = function (context)
}// 觀察者
function observer ()
}var mysubject = new subject();
mysubject.addobsever(new observer);
mysubject.notify("hello world");
發布/訂閱模式,訂閱者把自己想訂閱的事件註冊到排程中心,當該事件觸發時候,發布者發布該事件到排程中心(順帶上下文),由排程中心統一排程訂閱者註冊到排程中心的處理**。
比如有個介面是實時顯示天氣,它就訂閱天氣事件(註冊到排程中心,包括處理程式),當天氣變化時(定時獲取資料),就作為發布者發布天氣資訊到排程中心,排程中心就排程訂閱者的天氣處理程式。
// 發布、訂閱模式
var pubsub = {};
(function (myobject);
var subuid = -1;
// 發布指定訂閱
myobject.publish = function (topic, args)
var subscribers = topics[topic];
var len = subscribers ? subscribers.length : 0;
while(len--)
return this;
}// 向訂閱中心新增訂閱
myobject.subscribe = function (topic, func)
var token = (++subuid).tostring();
topics[topic].push()
return token;
}// 向訂閱中移除訂閱
myobject.unsubscribe = function (token) }}
}return this;
};})(pubsub);
pubsub.subscribe("test", ()=>);
pubsub.publish("test");
雖然兩種模式都存在訂閱者和發布者(具體觀察者可認為是訂閱者、具體目標可認為是發布者),但是觀察者模式是由具體目標排程的,而發布/訂閱模式是統一由排程中心調的,所以觀察者模式的訂閱者與發布者之間是存在依賴的,而發布/訂閱模式則不會。
兩種模式都可以用於鬆散耦合,改進**管理和潛在的復用
js 發布 訂閱模式(觀察者模式)
物件間的一種一對多的關係,當乙個物件發生改變時,所有依賴它的物件都會得到通知。比如wb上的明星和其粉絲的關係,粉絲在wb上訂閱了明星,所以當明星在wb上發表動態時所有粉絲都將得到通知。js具體實現 事件 有三個角色 訂閱者 subscriber 訊息分發器 msgdistributor wb例子 d...
js 觀察者和訂閱發布模式
之前一直都認為觀察者模式和發布訂閱模式是一回事,包括網上的很多文章也是這麼寫的,但有一次面試中被問到兩者的區別,直接懵了答不出來,經過最近的一些學習,慢慢理解了兩者的不同。在我看來,兩者最主要的區別在於是否有中間的排程中心。觀察者模式把訂閱者維護在發布者這裡,需要發布訊息時直接發訊息給訂閱者。在觀察...
js觀察者模式發布 訂閱
實習期結束,最近回到學校開始學習node.js,node果然是強大。不過在涉及到檔案操作的時候,發現要大量使用非同步回掉操作。以前在寫頁面的時候,從沒這麼多非同步操作,只有在使用 setinterval 和 xmlhttprequest 時了解了一下非同步程式設計。這次在學習node的過程中,把非同...