摘要:一什么是觀察者模式觀察者模式,引用維基百科的說法,一個目標對象管理所有相依與它的觀察者對象,并在它本身狀態(tài)改變時發(fā)生通知。四觀察者模式的用途觀察者模式主要用于解耦合,一個對象變了,可以通知多個對象,而不是在回調(diào)里來處理各種情況。
一、什么是觀察者模式
觀察者模式,引用維基百科的說法,一個目標對象管理所有相依與它的觀察者對象,并在它本身狀態(tài)改變時發(fā)生通知。這通常通過調(diào)用各觀察者所提供的方法來實現(xiàn)。在前端應用的范圍還挺多,最常見的事件監(jiān)聽,addEventListener,我們在一個元素上注冊了各類事件,而當對象發(fā)生相應改變時,通過調(diào)用綁定的事件告訴觀察者。就相當于在一個對象上綁定了各類觀察者。
舉個與前端不相關的例子,小偷警察的故事。小偷數(shù)量就是我們這里的目標對象,有三個警察負責看管(觀察者),當小偷數(shù)量大于3了,一個警察要去報告上級,一個警察要去警告市民引起重視,一個去和小偷談話。在程序里通過調(diào)用這三個警察的方法來相當于告訴這三個警察小偷數(shù)量大于3了。
二、用代碼看觀察者模式思路
/* 被觀察類 addObserver()方法把觀察者對象添加到觀察者對象列表中 setChange()方法用來設置一個內(nèi)部標志位注明數(shù)據(jù)發(fā)生了變化 notifyObservers()方法會去調(diào)用觀察者對象列表中所有的Observer的update()方法,通知它們數(shù)據(jù)發(fā)生了變化。 */ function Observable(){ this.observerArray = new Set(); this.updateFlage = false; } Observable.prototype.addObserver = function(data){ this.observerArray.add(data); } Observable.prototype.setChange = function(){ this.updateFlage = true; } Observable.prototype.notifyObservers = function(data){ if(this.updateFlage){ for(let item of this.observerArray){ item.update(data) } } this.updateFlage = false } /* 觀察者類 實現(xiàn)Observer接口的唯一方法update */ function Observer(){ this.update = function(){ } }
皮一下,這其實是看了Java里的觀察者模式思想,我用Js實現(xiàn)了一下。因為我看這個實現(xiàn)思路是更能體會到觀察者模式的。這里有兩個類,一個是被觀察類,實現(xiàn)了上述三個方法,一個是觀察者類。每個觀察者都有update方法,當被觀察者改變了,執(zhí)行相應的觀察者的update方法來通知觀察者被觀察者改變了。下面看示例:
function thief(){ var data = 0; Observable.call(this); this.setData = function(param){ data = param; if(data > 3){ this.setChange(); } this.notifyObservers(); } this.getData = function(){ return data } } thief.prototype = new Observable(); thief.prototype.constructor = thief; let thief1 = new thief(); let police1 = new Observer; let police2 = new Observer; thief1.addObserver(police1) thief1.addObserver(police2) police1.update = function(){ console.log("警察1接收到現(xiàn)在有"+thief1.getData()+"個小偷") } police2.update = function(){ console.log("警察2接收到現(xiàn)在有"+thief1.getData()+"個小偷") } thief1.setData(1) //無輸出 thief1.setData(4) //警察1接收到現(xiàn)在有4個小偷 警察2接收到現(xiàn)在有4個小偷
這個例子小偷繼承了被觀察者,當小偷內(nèi)部數(shù)據(jù)大于3的時候,就通知觀察各個警察引起重視。因為是參照Java的思想來的,所以看到實現(xiàn)是通過將小偷繼承被觀察者類,警察繼承觀察者類。這個結構其實用java來寫很清晰,觀察者的模式也體現(xiàn)的很清晰,能幫助我們很好的理解觀察者模式,值得借鑒。比起前端有些寫法在被觀察中存入對應的觀察者,和觀察者的回調(diào),這種寫法其實更分離。
三、前端代碼寫觀察者模式
前端的寫法跟Java里的實現(xiàn)類是有差別的,看代碼:
/** * 實現(xiàn)一個類 * on():存入被觀察者 * fire():手動觸發(fā)某個觀察者,可帶參數(shù) * delete():刪除指定觀察者 * update():被觀察者更新了,執(zhí)行觀察者回調(diào)通知觀察者 * one():某個觀察者只執(zhí)行一次 * 可鏈式調(diào)用 */ function Emiter(){ this.storage = new Map(); } Emiter.prototype.on = function(key,callback){ this.storage.set(key,callback); return this } Emiter.prototype.fire = function(key,data){ this.storage.has(key) ? this.storage.get(key)(data) : console.log("請先注冊對應的事件"); return this } Emiter.prototype.delete = function(key){ this.storage.has(key) ? this.storage.delete(key) : console.log("請先注冊對應的事件"); return this } Emiter.prototype.update = function(data){ for (let [key, value] of this.storage) { value(data); } return this } Emiter.prototype.one = function(key,data){ if(this.storage.has(key)){ this.storage.get(key)(data); this.storage.delete(key); }else{ console.log("請先注冊對應的事件") } return this } //示例 let emiter = new Emiter(); emiter.on("view1",function(data){ console.log("view1收到的數(shù)據(jù)"+data) }) emiter.on("event",function(){ console.log("emiter") }).on("click",function(){ console.log("click啦") }) emiter.update([1,2,3]) //view1收到的數(shù)據(jù)1,2,3 emiter click啦
前端拋開一些復雜規(guī)范性,可以直接把觀察者和觀察者的回調(diào)保存在被觀察者里,當被觀察者更新了,執(zhí)行所有觀察者的回調(diào)。這里之所以有one fire 等方法提供,主要是考慮前端addEventListner也是采用觀察者模式,所以一起提供了。只不過更相當于一對一模式,沒有對應的update,更新所有觀察者的操作。我們這里探討的設計模式應該是on update delete為主線。
四、觀察者模式的用途
觀察者模式主要用于解耦合,一個對象變了,可以通知多個對象,而不是在回調(diào)里來處理各種情況。一個場景有個模塊獲取了數(shù)據(jù),其他多個view層都需要用到這個數(shù)據(jù)。我們的做法可能是會在獲取數(shù)據(jù)后的模塊回調(diào)里進行各個view層的處理,那如果后續(xù)某個模塊的相應業(yè)務變了,我們可能還得回來改這個回調(diào)函數(shù)。那如果通過觀察者模式,我們可以優(yōu)化為,每個模塊完全分離,當數(shù)據(jù)回來時告知每個模塊即可。以后模塊要改變獲取數(shù)據(jù)后的處理,各個模塊自己去更新。
我現(xiàn)在在想,event對象,是不是內(nèi)部實現(xiàn),是在dom改變時傳的參數(shù),而在調(diào)用相關事件時能拿到這個回調(diào)的參數(shù)。
之前看文檔,Vue里數(shù)據(jù)變了,如何更新view,用的也是觀察者模式,只不過不是這種實現(xiàn)代碼,后續(xù)更新。
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/108225.html
摘要:觀察者模式定義設計模式中對的定義一個對象稱為維持一系列依賴于它觀察者的對象,將有關狀態(tài)的任何變更自動通知給它們。如圖模式比較觀察者模式則多了一個類似于話題調(diào)度中心的流程,發(fā)布者和訂閱者解耦。 Obeserver(觀察者)模式 定義 《js設計模式》中對Observer的定義:一個對象(稱為subject)維持一系列依賴于它(觀察者)的對象,將有關狀態(tài)的任何變更自動通知給它們。 《設計模...
摘要:關鍵概念理解觀察者設計模式中主要區(qū)分兩個概念觀察者指觀察者對象,也就是消息的訂閱者被觀察者指要觀察的目標對象,也就是消息的發(fā)布者。 原文首發(fā)于微信公眾號:jzman-blog,歡迎關注交流! 最近補一下設計模式相關的知識,關于觀察者設計模式主要從以下幾個方面來學習,具體如下: 什么是觀察者設計模式 關鍵概念理解 通知觀察者的方式 觀察者模式的實現(xiàn) 觀察者模式的優(yōu)缺點 使用場景 下面...
摘要:觀察者模式的使用場景比如你微博關注了一個人,那么這個人發(fā)布的微博就會推送到你這。 Java設計模式之觀察者模式 一直想寫一篇學習觀察者模式的總結沒有契機,今天學習阻塞隊列的原理時候看到在實現(xiàn)生產(chǎn)者消費者的時候用到了通知模式,就是所謂的觀察者模式,正好順便整理一下。 1. 簡介 觀察者模式定義對象間的一種一對多的依賴關系,當一個對象的狀態(tài)發(fā)生改變時,所有依賴于它的對象都得到通知并被自動更...
摘要:概念觀察者模式屬于行為模式,是定義對象間的一種一對多的依賴關系,以便當一個對象的狀態(tài)發(fā)生改變時,所有依賴于它的對象都得到通知并自動刷新。觀察者模式符合接口隔離原則,實現(xiàn)了對象之間的松散耦合。 概念 觀察者模式屬于行為模式,是定義對象間的一種一對多的依賴關系,以便當一個對象的狀態(tài)發(fā)生改變時,所有依賴于它的對象都得到通知并自動刷新。 當一個對象狀態(tài)發(fā)生改變后,會影響到其他幾個對象的改變,這...
摘要:最近在學的設計模式,看到了觀察者模式,在此寫下一點理解問題假如一個小販,他把產(chǎn)品的價格提升了,不同的消費者會對此產(chǎn)生不同的反應。 最近在學php 的設計模式, 看到了觀察者模式,在此寫下一點理解: 問題: 假如一個小販, 他把產(chǎn)品的價格提升了, 不同的消費者會對此產(chǎn)生不同的反應。一般的編程模式無非是獲取提升的價格,然后獲取所有的消費者,再循環(huán)每個消費者, 不同的消費者根據(jù)價格漲幅...
摘要:監(jiān)聽模式又名觀察者模式發(fā)布訂閱模式源監(jiān)聽器模式,模式的核心是設計時要區(qū)分誰是被觀察者,誰是觀察者。 監(jiān)聽模式 又名觀察者模式、發(fā)布/訂閱模式、源-監(jiān)聽器(Source/Listener)模式,模式的核心是:設計時要區(qū)分誰是被觀察者,誰是觀察者。被觀察者至少有三個方法,添加觀察者、刪除觀察者、監(jiān)聽目標變化并通知觀察者;觀察者這至少包含一個方法,當接收到被觀察者的通知時,做出相應的處理(即...
閱讀 2222·2021-11-18 10:02
閱讀 3480·2021-11-15 11:36
閱讀 1116·2019-08-30 14:03
閱讀 724·2019-08-30 11:08
閱讀 2761·2019-08-29 13:20
閱讀 3287·2019-08-29 12:34
閱讀 1375·2019-08-28 18:30
閱讀 1642·2019-08-26 13:34