摘要:最近被人問(wèn)到設(shè)計(jì)模式,觀察者模式和發(fā)布訂閱模式二者有什么區(qū)別。觀察者模式觀察者模式,目標(biāo)和觀察者是基類,目標(biāo)提供維護(hù)觀察者的一系列方法,觀察者提供更新接口。
最近被人問(wèn)到設(shè)計(jì)模式,觀察者(Observer)模式和發(fā)布(Publish)/訂閱(Subscribe)模式二者有什么區(qū)別。其實(shí)這兩種模式還是有些許差異的,本質(zhì)上的區(qū)別是調(diào)度的方式不同。
觀察者模式觀察者模式,目標(biāo)和觀察者是基類,目標(biāo)提供維護(hù)觀察者的一系列方法,觀察者提供更新接口。具體觀察者和具體目標(biāo)繼承各自的基類,然后具體觀察者把自己注冊(cè)到具體目標(biāo)里,在具體目標(biāo)發(fā)生變化時(shí)候,調(diào)度觀察者的更新方法。
比如有個(gè)“天氣中心”的具體目標(biāo)A,專門監(jiān)聽(tīng)天氣變化,而有個(gè)顯示天氣的界面的觀察者B,B就把自己注冊(cè)到A里,當(dāng)A觸發(fā)天氣變化,就調(diào)度B的更新方法,并帶上自己的上下文。
示例
// 觀察者列表 function ObserverList () { this.observerList = []; } ObserverList.prototype.add = function (obj) { return this.observerList.push(obj); } ObserverList.prototype.count = function () { return this.observerList.length; } ObserverList.prototype.get = function (index) { if (index > -1 && index < this.observerList.length) { return this.observerList[index]; } } ObserverList.prototype.indexOf = function (obj, startIndex) { var i = startIndex || 0; while (i < this.observerList.length) { if (this.observerList[i] === obj) { return i; } i++; } return -1; } ObserverList.prototype.removeAt = function (index) { this.observerList.splice(index, 1); } // 目標(biāo) function Subject () { this.observers = new ObserverList(); } Subject.prototype.addObsever = function (observer) { this.observers.add(observer); } Subject.prototype.removeObsever = function (observer) { this.observers.removeAt(this.observers.indexOf(observer, 0)); } Subject.prototype.notify = function (context) { var observerCount = this.observers.count(); for(var i = 0; i < observerCount; i++) { this.observers.get(i).update(context); } } // 觀察者 function Observer () { this.update = function (context) { console.log(context); } } var mySubject = new Subject(); mySubject.addObsever(new Observer); mySubject.notify("hello world");發(fā)布/訂閱模式
發(fā)布/訂閱模式,訂閱者把自己想訂閱的事件注冊(cè)到調(diào)度中心,當(dāng)該事件觸發(fā)時(shí)候,發(fā)布者發(fā)布該事件到調(diào)度中心(順帶上下文),由調(diào)度中心統(tǒng)一調(diào)度訂閱者注冊(cè)到調(diào)度中心的處理代碼。
比如有個(gè)界面是實(shí)時(shí)顯示天氣,它就訂閱天氣事件(注冊(cè)到調(diào)度中心,包括處理程序),當(dāng)天氣變化時(shí)(定時(shí)獲取數(shù)據(jù)),就作為發(fā)布者發(fā)布天氣信息到調(diào)度中心,調(diào)度中心就調(diào)度訂閱者的天氣處理程序。
// 發(fā)布、訂閱模式 var pubsub = {}; (function (myObject){ var topics = {}; var subUid = -1; // 發(fā)布指定訂閱 myObject.publish = function (topic, args) { if (!topics[topic]) { return false; } var subscribers = topics[topic]; var len = subscribers ? subscribers.length : 0; while(len--) { subscribers[len].func(topic, args); } return this; } // 向訂閱中心添加訂閱 myObject.subscribe = function (topic, func) { if (!topics[topic]) { topics[topic] = []; } var token = (++subUid).toString(); topics[topic].push({ token: token, func: func }) return token; } // 向訂閱中移除訂閱 myObject.unSubscribe = function (token) { for (var m in topics) { if (topics[m]) { for (var i = 0, j = topics[m].length; i < j; i++) { if (topics[m][i].token === token) { topics[m].splice(i, 1); return token; } } } } return this; }; })(pubsub); pubsub.subscribe("test", ()=>{console.log("hello world")}); pubsub.publish("test");總結(jié)
雖然兩種模式都存在訂閱者和發(fā)布者(具體觀察者可認(rèn)為是訂閱者、具體目標(biāo)可認(rèn)為是發(fā)布者),但是觀察者模式是由具體目標(biāo)調(diào)度的,而發(fā)布/訂閱模式是統(tǒng)一由調(diào)度中心調(diào)的,所以觀察者模式的訂閱者與發(fā)布者之間是存在依賴的,而發(fā)布/訂閱模式則不會(huì)。
兩種模式都可以用于松散耦合,改進(jìn)代碼管理和潛在的復(fù)用
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/99131.html
摘要:發(fā)布者注冊(cè)發(fā)布訂閱者自動(dòng)打印消息消息觀察者模式與發(fā)布訂閱模式類似。在此種模式中,一個(gè)目標(biāo)物件在它本身的狀態(tài)改變時(shí)主動(dòng)發(fā)出通知,觀察者收到通知從而使他們的狀態(tài)自動(dòng)發(fā)生變化。 做為非科班出身的前端er,每次聽(tīng)到設(shè)計(jì)模式都感覺(jué)很高大上,總感覺(jué)這些東西是造火箭原子彈用的,距離我們這些造螺絲釘很遙遠(yuǎn)。但是最近在做一個(gè)聊天消息的業(yè)務(wù)時(shí),發(fā)現(xiàn)貌似用上發(fā)布訂閱模式業(yè)務(wù)就很清晰了。創(chuàng)建一個(gè)消息類當(dāng)作發(fā)布...
摘要:觀察者模式定義設(shè)計(jì)模式中對(duì)的定義一個(gè)對(duì)象稱為維持一系列依賴于它觀察者的對(duì)象,將有關(guān)狀態(tài)的任何變更自動(dòng)通知給它們。如圖模式比較觀察者模式則多了一個(gè)類似于話題調(diào)度中心的流程,發(fā)布者和訂閱者解耦。 Obeserver(觀察者)模式 定義 《js設(shè)計(jì)模式》中對(duì)Observer的定義:一個(gè)對(duì)象(稱為subject)維持一系列依賴于它(觀察者)的對(duì)象,將有關(guān)狀態(tài)的任何變更自動(dòng)通知給它們。 《設(shè)計(jì)模...
摘要:概念觀察者模式被廣泛地應(yīng)用于客戶端編程中。所有的瀏覽器事件,等都是使用觀察者模式的例子。在觀察者模式中,一個(gè)對(duì)象訂閱另一個(gè)對(duì)象的指定活動(dòng)并得到通知,而不是調(diào)用另一個(gè)對(duì)象的方法。此外,觀察者模式還可用于實(shí)現(xiàn)數(shù)據(jù)綁定。 概念 觀察者模式被廣泛地應(yīng)用于JavaScript客戶端編程中。所有的瀏覽器事件(mouseover,keypress等)都是使用觀察者模式的例子。這種模式的另一個(gè)名字叫自...
摘要:期設(shè)計(jì)模式如何理解觀察者發(fā)布訂閱模式定義觀察者模式又叫發(fā)布訂閱模式,它定義了一種一對(duì)多的關(guān)系,讓多個(gè)觀察者對(duì)象同時(shí)監(jiān)聽(tīng)某一個(gè)主題對(duì)象,這個(gè)主題對(duì)象的狀態(tài)發(fā)生變化時(shí)就會(huì)通知所有的觀察者對(duì)象,使得它們能夠自動(dòng)更新自己生活實(shí)例理解你今天去看一個(gè) 20190411期 設(shè)計(jì)模式-如何理解觀察者(發(fā)布訂閱)模式? 定義: 觀察者模式又叫發(fā)布訂閱模式(Publish/Subscribe),它定義了一...
摘要:觀察者模式機(jī)動(dòng)建立一種對(duì)象與對(duì)象之間的依賴關(guān)系,一個(gè)對(duì)象發(fā)生改變時(shí)將自動(dòng)通知其他對(duì)象,其他對(duì)象將相應(yīng)做出反應(yīng)。 觀察者模式模式簡(jiǎn)介 觀察者模式(又被稱為發(fā)布-訂閱(Publish/Subscribe)模式,屬于行為型模式的一種,它定義了一種一對(duì)多的依賴關(guān)系,讓多個(gè)觀察者對(duì)象同時(shí)監(jiān)聽(tīng)某一個(gè)主題對(duì)象。這個(gè)主題對(duì)象在狀態(tài)變化時(shí),會(huì)通知所有的觀察者對(duì)象,使他們能夠自動(dòng)更新自己。 觀察者模式機(jī)動(dòng)...
閱讀 2175·2023-04-25 20:45
閱讀 1088·2021-09-22 15:13
閱讀 3660·2021-09-04 16:48
閱讀 2589·2019-08-30 15:53
閱讀 944·2019-08-30 15:44
閱讀 965·2019-08-30 15:43
閱讀 1016·2019-08-29 16:33
閱讀 3445·2019-08-29 13:08