摘要:生活中的觀察者模式就如我們在專賣店預定商品如蘋果手機,我們會向專賣店提交預定申請,然后店家受申請,正常這樣就完事了。中的觀察者模式在中觀察者模式的實現主要用事件模型。缺點使用全局的觀察者模式會明顯降低對象之間的聯系。
觀察者模式又叫做發布-訂閱模式。這是一種一對多的對象依賴關系,當被依賴的對象的狀態發生改變時,所有依賴于它的對象都將得到通知。
生活中的觀察者模式就如我們在專賣店預定商品(如:蘋果手機),我們會向專賣店提交預定申請,然后店家受申請,正常這樣就完事了。假如,近段時間蘋果手機的需求很大,而商品有限,那么商家就會要這些果粉預留電話等待通知,等到手機一到,商家就會遍歷果粉預留信息,然后發通知給這些果粉。生活中商家強調客戶在家等通知即可,并且說一有消息就會通知客戶,而不會傻到要客戶主動打電話詢問,這樣不僅客戶的代價比較大,商家的負荷更大,用戶的輪詢方式也從打電話變成了查看短信息。
觀察者模式的優勢發布和訂閱這兩個對象是松耦合地聯系在一起的,它們不用彼此熟悉內部的實現細節,但這不影響它們之間的通信,它們只要知道彼此需要做什么就行。當有新訂閱者增加時,發布者不需要任何更改,同樣的當發布者改變時,訂閱者也不會受到影響。
就像新聞聯播一樣里面的央視主持人換了,也不影響我們看央視的新聞聯播,同樣你看或不看新聞聯播,對央視來說也無影響。
在異步通信中觀察者模式也是大有好處,發布者只需按順序的發布事件即可,而訂閱者只需在異步運行期間訂閱相關事件即可。
JavaScript中的觀察者模式在JavaScript中觀察者模式的實現主要用事件模型。
DOM事件document.body.addEventListener("click", function() { console.log("hello world!"); });
相信這樣的代碼不少的同學都寫過,但我要說這其實就是一種觀察者模式的實現,可能一些童鞋還不信,那么看一看修改后的代碼。
// 發布者 var pub = function() { console.log("歡迎訂閱!") } // 訂閱者 var sub = document.body; // 訂閱者實現訂閱 sub.addEventListener("click", pub, false);
訂閱者可以任意的添加,發布者也可以隨意的修改。
自定義事件雖然,使用dom事件可以輕松解決我們開發中的一部分問題;但是還有一些問題需要我們使用自定義事件來完成。
那面就說一說如何用自定義事件實現代理。
我們還以預定手機為例,參考dom事件的原理來實現觀察者模式,用用戶的電話號碼作為類型,用戶的定購信息用一個回調函數來表示。
基本概念定義如下:
商家: 發布者
客戶: 訂閱者
緩存列表:記錄客戶的電話,方便商家遍歷發通知消息給客戶
注:緩存列表,我將它定義為一個對象,用戶的電話號碼作為key,用戶的預定信息是個數組作為value。
代碼實現如下:
// 定義商家 var merchants = {}; // 定義預定列表 merchants.orderList = {}; // 將增加的預訂者添加到預定客戶列表中 merchants.listen = function(id, info) { if(!this.orderList[id]) { this.orderList[id] = []; } this.orderList[id].push(info); console.log("預定成功") }; //發布消息 merchants.publish = function() { var id = Array.prototype.shift.call(arguments); var infos = this.orderList[id]; // 判斷是否有預訂信息 if(!infos || infos.length === 0) { console.log("您還沒有預訂信息!"); return false; } // 如果有預訂信息,則循環打印 for (var i = 0, info; info = infos[i++];) { console.log("尊敬的客戶:"); info.apply(this, arguments); console.log("已經到貨了"); } }; // 定義一個預訂者customerA,并指定預定信息 var customerA = function() { console.log("黑色至尊版一臺"); }; // customerA 預定手機,并留下預約電話 merchants.listen("15888888888", customerA); // 預定成功 // 商家發布通知信息 merchants.publish("15888888888"); /** 尊敬的客戶: 黑色至尊版一臺 已經到貨了 */取消訂閱
當然,現實中我們可以預定,那么也可以取消預定。其實取消預定的方式也比較簡單,就是將客戶從預定列表中清除出去。代碼實現如下:
merchants.remove = function(id, fn) { var infos = this.orderList[id]; if(!infos) return false; if(!fn) { infos && (infos.length = 0); } else { for(var i = 0, len = infos.length; i < len; i++) { if(infos[i] === fn) { infos.splice(i, 1); } } } }; merchants.remove("15888888888", customerA); merchants.publish("15888888888"); // 您還沒有預訂信息!全局的觀察者模式
實現的代碼結構如下:
var observer = (function() { var orderList = {}, listen, publish, remove; listen = function(id, fn) { ... }; publish = function() { ... }; remove = function(id, fn) { ... }; return { listen: listen, publish: publish, remove: remove } })();
優點:
使用了全局的觀察者模式后,我們不用管商家是誰,只要他能提供我們所需要的東西即可;而且我們也避免了為不同的商家都創建listen,publish,remove方法,這樣可以減少資源的浪費。
缺點:
使用全局的觀察者模式會明顯降低對象之間的聯系。一些方法將會被隱藏,而有時我們恰恰需要這些方法的暴露。
是先訂閱,還是先發布在我被問到這個問題時,我也是一愣,當時腦袋里就冒出了‘你怎么不問是先有雞,還是先有蛋’這樣的想法。
按照我的理解我們實現觀察者模式,都是訂閱者先訂閱,然后接收發布者的通知消息。沒有反過來想,發布者先發布一條消息,然后等訂閱者接收,因為在我的想象中,如果沒有訂閱者,這消息怎么成功發布。
后來有人跟我說有這樣的業務實現,當時我就不假思索的問什么業務,他說QQ的離線模式。這種先發布后訂閱的形式是將信息先存儲起來,等到訂閱者訂閱,就立即將信息發送給訂閱者。如:當我們將QQ調到離線模式,我們就無法接收信息;當我們將QQ調到登錄模式,就馬上收在離線模式期間接收到的信息。
這樣的例子在生活中也有很多,還拿天氣預報,它也可以理解為是先發布,我們后訂閱的模式。天預報信息會發布在網上,存儲在各個服務器上,我們需要時打開手機就可以得到。
注:提到觀察者模式我們就不得不說一下推模型和拉模型。推模型在事件發生時,發布者會將變化狀態和數據都推送給訂閱者;拉模型在事件發生時,發布者只會給訂閱者一個狀態改變通知,訂閱者會根據發布者提供的接口主動拉取數據。
設計模式周周講
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/92831.html
摘要:發布訂閱模式訂閱者把自己想訂閱的事件注冊到調度中心,當發布者發布該事件到調度中心,也就是該事件觸發時,由調度中心統一調度訂閱者注冊到調度中心的處理代碼。 發布-訂閱模式,看似陌生,其實不然。工作中經常會用到,例如 Node.js EventEmitter 中的 on 和 emit 方法;Vue 中的 $on 和 $emit 方法。他們都使用了發布-訂閱模式,讓開發變得更加高效方便。 一...
摘要:原文鏈接常用設計模式設計模式設計模式是一種在長時間的經驗與錯誤中總結出來可服用的解決方案。用來模擬接口的相關操作我很帥通過適配器函數來調用目的我很帥學習資料聽飛狐聊設計模式系列設計模式湯姆大叔 原文鏈接: JavaScript常用設計模式 設計模式 設計模式是一種在長時間的經驗與錯誤中總結出來可服用的解決方案。 設計模式主要分為3類: 創建型設計模式:專注于處理對象的創建 Const...
摘要:觀察者模式維護單一事件對應多個依賴該事件的對象關系發布訂閱維護多個事件主題及依賴各事件主題的對象之間的關系觀察者模式是目標對象直接觸發通知全部通知,觀察對象被迫接收通知。 觀察者模式(Observer) 觀察者模式:定義了對象間一種一對多的依賴關系,當目標對象 Subject 的狀態發生改變時,所有依賴它的對象 Observer 都會得到通知。 簡單點:女神有男朋友了,朋友圈曬個圖,甜...
摘要:原文精髓,觀察者模式和事件交互邏輯更需要設計模式設計模式將人們在以往的開發過程中的經驗加以總結,以指導后人。的事件根據上面討論,要實現觀察者模式,事件是非常重要的機制??偨Y雖然是模式的框架,但是其核心卻是界面的觀察者模式和事件機制。 前言 本人并非專業的前端,只是由于需要被迫轉做一段時間的前端,一段時間以來開始探索javascript上的MVC模式,最終打算從Backbone下手。在...
摘要:設計模式與開發實踐讀書筆記。發布訂閱模式又叫觀察者模式,它定義了對象之間的一種一對多的依賴關系。附設計模式之發布訂閱模式觀察者模式數據結構和算法系列棧隊列優先隊列循環隊列設計模式系列設計模式之策略模式 《JavaScript設計模式與開發實踐》讀書筆記。 發布-訂閱模式又叫觀察者模式,它定義了對象之間的一種一對多的依賴關系。當一個對象的狀態發生改變時,所有依賴它的對象都將得到通知。 例...
閱讀 1093·2021-10-12 10:11
閱讀 877·2019-08-30 15:53
閱讀 2286·2019-08-30 14:15
閱讀 2961·2019-08-30 14:09
閱讀 1197·2019-08-29 17:24
閱讀 972·2019-08-26 18:27
閱讀 1283·2019-08-26 11:57
閱讀 2146·2019-08-23 18:23