摘要:概念觀察者模式被廣泛地應(yīng)用于客戶端編程中。所有的瀏覽器事件,等都是使用觀察者模式的例子。在觀察者模式中,一個對象訂閱另一個對象的指定活動并得到通知,而不是調(diào)用另一個對象的方法。此外,觀察者模式還可用于實現(xiàn)數(shù)據(jù)綁定。
概念
觀察者模式被廣泛地應(yīng)用于JavaScript客戶端編程中。所有的瀏覽器事件(mouseover,keypress等)都是使用觀察者模式的例子。這種模式的另一個名字叫“自定義事件”,意思是這些事件是被編寫出來的,和瀏覽器觸發(fā)的事件相對。它還有另外一個名字叫“訂閱者/發(fā)布者”模式。
使用這個模式的最主要目的就是促進代碼觸解耦。在觀察者模式中,一個對象訂閱另一個對象的指定活動并得到通知,而不是調(diào)用另一個對象的方法。訂閱者也被叫作觀察者,被觀察的對象叫作發(fā)布者或者被觀察者(譯注:subject,不知道如何翻譯,第一次的時候譯為“主體”,第二次譯時覺得不妥,還是直接叫被觀察者好了)。當(dāng)一個特定的事件發(fā)生的時候,發(fā)布者會通知(調(diào)用)所有的訂閱者,同時還可能以事件對象的形式傳遞一些消息。 (摘自javascript 模式一書)
維基百科定義:在軟件架構(gòu)中,發(fā)布-訂閱是一種消息范式,消息的發(fā)送者(稱為發(fā)布者)不會將消息直接發(fā)送給特定的接收者(稱為訂閱者)。而是將發(fā)布的消息分為不同的類別,無需了解哪些訂閱者(如果有的話)可能存在。同樣的,訂閱者可以表達對一個或多個類別的興趣,只接收感興趣的消息,無需了解哪些發(fā)布者(如果有的話)存在。
理解觀察者模式:摘自 http://www.cnblogs.com/tugenh...
JS傳統(tǒng)事件就是一個觀察者模式,之所以要有觀察者模式,是因為有時候和傳統(tǒng)事件無關(guān)的事件,比如:2個或者更多模塊的直接通信問題,比如說我有個index.html頁面,我有很多JS文件,比如:
a.js: function a(){}; b.js: function b(){}; c.js function c(){}; 等等。后面還有許多這樣的JS,那么我要在index.html初始化這些函數(shù)的話,我需要這樣調(diào)用a();b();c()等等,也就是說頁面調(diào)用的時候 我要這樣調(diào)用,增加了依賴性,我要知道有多少個函數(shù)要這樣初始化調(diào)用,但是如果我們現(xiàn)在用觀察者模式就不需要知道有哪些訂閱者,比如一個模塊(或者多個模塊)訂閱了一個主題(或者事件),另一個模塊發(fā)布這個主題時候,訂閱這個主題模塊就可以執(zhí)行了,觀察者主要讓訂閱者與發(fā)布者解耦,發(fā)布者不需要知道哪些模塊訂閱了這個主題,它只管發(fā)布這個主題就可以了,同樣訂閱者也無需知道那個模塊會發(fā)布這個主題,它只管訂閱這個主題就可以了。這樣2個模塊(或更多模塊)就實現(xiàn)了關(guān)聯(lián)了。而不需要和上面代碼一樣,我要知道哪些模塊要初始化,我要怎樣初始化。這只是一個簡單的列子解釋觀察者模式要使用在什么地方,我也看過很多博客關(guān)于這方面的資料,但是很多人寫博客只是講了如何實現(xiàn)觀察者模式及觀察者模式的好處,并沒有講我們什么時候該使用觀察者模式,所以我列舉了上面的列子,就是多個不同業(yè)務(wù)模塊需要相互關(guān)聯(lián)的時候,可以使用觀察者模式。就好比requireJS,seaJS,KISSY解決依賴的問題一樣(比如A依賴于B,B依賴于C,只要一個解決入口文件,其他都會異步加載出來一樣)。也就是說各個模塊之間的關(guān)聯(lián)性可以使用觀察者模式來設(shè)計。
代碼實現(xiàn):在該篇博客(https://www.cnblogs.com/Lucky...。
(function(){ var Event = { on: function (type, handler) { if (!this.handlers) { // this.handlers = {}; Object.defineProperty(this, "handlers", { value: {}, enumerable: false, // important 避免拷貝Event時污染handlers configurable: true, writable: true }) } if (typeof this.handlers[type] === "undefined") { this.handlers[type] = []; } this.handlers[type].push(handler); }, emit: function (eventName) { if (this.handlers[arguments[0]] instanceof Array) { var handlers = this.handlers[arguments[0]]; for (var i=0; i可在我的github上下載上述代碼(https://github.com/ylzsmallsu...),并包含JavaScript模式中觀察者模式例子。
此外,觀察者模式還可用于實現(xiàn)數(shù)據(jù)綁定。思想:使用數(shù)據(jù)特性來為 HTML 代碼進行綁定,所有被綁定在一起的 JavaScript 對象和 DOM 元素都會訂閱一個 PubSub 對象。只要 JavaScript 對象或者一個 HTML 輸入元素監(jiān)聽到數(shù)據(jù)的變化時,就會觸發(fā)綁定到 PubSub 對象上的事件,從而其他綁定的對象和元素都會做出相應(yīng)的變化。
參考文章談?wù)凧S的觀察者模式(自定義事件):https://www.cnblogs.com/Lucky...
數(shù)據(jù)雙向綁定的分析和簡單實現(xiàn):https://zhuanlan.zhihu.com/p/...
JavaScript 實現(xiàn)簡單的雙向數(shù)據(jù)綁定(譯):http://zqianduan.com/2016/03/...
理解javascript觀察者模式(訂閱者與發(fā)布者):http://www.cnblogs.com/tugenh...
本篇文章主要是對查閱的幾篇文檔集中梳理,有興趣的可以翻閱以上參考文章。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/98048.html
摘要:觀察者模式與發(fā)布訂閱的區(qū)別在模式中,知道,同時還保留了的記錄。發(fā)布者訂閱者在大多情況下是異步方式使用消息隊列。圖片源于網(wǎng)絡(luò)侵權(quán)必刪如果以結(jié)構(gòu)來分辨模式,發(fā)布訂閱模式相比觀察者模式多了一個中間件訂閱器,所以發(fā)布訂閱模式是不同于觀察者模式的。 學(xué)習(xí)了一段時間設(shè)計模式,當(dāng)學(xué)到觀察者模式和發(fā)布訂閱模式的時候遇到了很大的問題,這兩個模式有點類似,有點傻傻分不清楚,博客起因如此,開始對觀察者和發(fā)布...
摘要:另一種關(guān)于組件的常見說法,是組件是為了重用。這件事情是前端特有的,受限制于的結(jié)構(gòu)。這一節(jié)的題目叫做混亂的組件通訊,我們來仔細掰扯一下細節(jié),因為組件模型雖然很常說但是對通訊過程沒有約定。 這個話題很難寫。 但是反過來說,愛因斯坦有句名言:如果你不能把一個問題向一個六歲孩子解釋清楚,那么你不真的明白它。 所以解釋清楚一個問題的關(guān)鍵,不是去擴大化,而是相反,最小化。 Lets begin. ...
摘要:在沒有環(huán)境下對進行單元測試的時候,應(yīng)用邏輯正確性是無法驗證的更新的時候,無法對的更新操作進行斷言。對是通過接口進行,在對進行不依賴環(huán)境的單元測試的時候。這里根據(jù)上面的例子給出了的單元測試樣例。年微軟工程師在自己的博客上首次公布了模式。 前言 做客戶端開發(fā)、前端開發(fā)對MVC、MVP、MVVM這些名詞不了解也應(yīng)該大致聽過,都是為了解決圖形界面應(yīng)用程序復(fù)雜性管理問題而產(chǎn)生的應(yīng)用架構(gòu)模式。網(wǎng)上...
閱讀 867·2021-09-06 15:02
閱讀 2492·2019-08-30 15:43
閱讀 2266·2019-08-30 11:26
閱讀 2429·2019-08-26 12:12
閱讀 3598·2019-08-23 18:24
閱讀 3338·2019-08-23 18:16
閱讀 752·2019-08-23 17:02
閱讀 2308·2019-08-23 15:34