摘要:觀察者模式定義設(shè)計(jì)模式中對的定義一個(gè)對象稱為維持一系列依賴于它觀察者的對象,將有關(guān)狀態(tài)的任何變更自動通知給它們。如圖模式比較觀察者模式則多了一個(gè)類似于話題調(diào)度中心的流程,發(fā)布者和訂閱者解耦。
Obeserver(觀察者)模式 定義
《js設(shè)計(jì)模式》中對Observer的定義:
一個(gè)對象(稱為subject)維持一系列依賴于它(觀察者)的對象,將有關(guān)狀態(tài)的任何變更自動通知給它們。
《設(shè)計(jì)模式:可服用面向?qū)ο筌浖幕A(chǔ)》中對Observer的定義:
一個(gè)或多個(gè)觀察者對目標(biāo)的狀態(tài)感興趣,它們通過將自己依附在目標(biāo)對象上以便注冊所感興趣的內(nèi)容。目標(biāo)狀態(tài)發(fā)生改變并且觀察者可能對這些改變感興趣,就會發(fā)送一個(gè)通知消息,調(diào)用每個(gè)觀察者的更新方法。當(dāng)觀察者不再對目標(biāo)感興趣時(shí),他們可以簡單地將自己從中分離。
下面看一個(gè)觀察者模式的例子:
//觀察者列表 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; 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.addObserver = function(observer) { this.observers.add(observer); }; Subject.prototype.removeObserver = 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(name, subject) { this.name = name; this.subject = subject; this.subscribe(this.subject); } Observer.prototype.update = function(context) { console.log("observer:" + this.name + " content:" + context); } Observer.prototype.subscribe = function(subject) { this.subject.addObserver(this); } var subject1 = new Subject(); var subject2 = new Subject(); var observer1 = new Observer("observer1", subject1); var observer2 = new Observer("observer2", subject1); var observer3 = new Observer("observer3", subject2); subject1.notify("999感冒靈"); subject2.notify("999胃泰"); //observer:observer1 content:999感冒靈 //observer:observer2 content:999感冒靈 //observer:observer3 content:999胃泰
常用的場景
網(wǎng)頁的事件綁定
Publish/Subscribe(發(fā)布/訂閱)模式下面我們來看一個(gè)發(fā)布訂閱的具體實(shí)現(xiàn);
var pubsub={}; (function(q){ var topics={}, subUid=-1, subscribers, len; //發(fā)布廣播事件,包含特定的topic名稱和參數(shù) q.publish=function(topic, args){ if(!topics[topic]){ return false; } subscribers=topics[topic]; len=subscribers ? subscribers.length : 0; while(len--){ subscribers[len].func(topic, args); } return this; }; q.subscribe=function(topic, func){ if(!topics[topic]){ topics[topic]=[]; } var token=(++subUid).toString(); topics[topic].push({ token:token, func:func }); return token; }; q.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); function log1(topic ,data){ console.log(topic , data); } function log2(topic ,data){ console.log("Topic is "+topic+" Data is "+data); } pubsub.subscribe("sss",log2); pubsub.subscribe("sss",log1); pubsub.subscribe("cccc",log2); pubsub.subscribe("aaa", log1); pubsub.publish("sss","aaaaa1"); pubsub.publish("cccc","ssssss"); pubsub.publish("aaa", "hahahahah"); //sss aaaaa1 //Topic is sss Data is aaaaa1 //Topic is cccc Data is ssssss //aaa hahahahah區(qū)別
Observer模式要求希望接收到主題通知的觀察者或?qū)ο蟊仨氂嗛唭?nèi)容改變的事件。如圖:
Publish/Subscribe模式比較觀察者模式則多了一個(gè)類似于話題調(diào)度中心的流程,發(fā)布者和訂閱者解耦。
觀察者模式更像是去咖啡店點(diǎn)咖啡,向店家點(diǎn)一杯咖啡,然后做好后店家會送過來,我和店家是直接有交互的。
發(fā)布訂閱模式就像是我們微信里面訂閱公眾號,發(fā)布者把文章發(fā)布到這個(gè)公眾號,我們訂閱公眾號后就會收到發(fā)布者發(fā)布的文章,我們可以關(guān)注和取消關(guān)注這個(gè)公眾號。
實(shí)際應(yīng)用promise
jquery的Callback內(nèi)部方法
感興趣的小伙伴可以移步自己動手實(shí)現(xiàn)一個(gè)Promise
JS設(shè)計(jì)模式系列文章JS設(shè)計(jì)模式之Obeserver(觀察者)模式、Publish/Subscribe(發(fā)布/訂閱)模式
JS設(shè)計(jì)模式之Factory(工廠)模式
JS設(shè)計(jì)模式之Singleton(單例)模式
JS設(shè)計(jì)模式之Facade(外觀)模式
JS設(shè)計(jì)模式之Module(模塊)模式、Revealing Module(揭示模塊)模式
JS設(shè)計(jì)模式之Mixin(混入)模式
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/109178.html
摘要:對解耦是很有用對。設(shè)計(jì)模式系列文章設(shè)計(jì)模式之觀察者模式發(fā)布訂閱模式設(shè)計(jì)模式之工廠模式設(shè)計(jì)模式之單例模式設(shè)計(jì)模式之外觀模式設(shè)計(jì)模式之模塊模式揭示模塊模式 工廠模式 提供一個(gè)通用的接口來創(chuàng)建對象 示例 //Car構(gòu)造函數(shù) function Car(option) { this.doors = option.doors || 4 this.color = option...
摘要:定義限制類的實(shí)例化次數(shù)只能是一次。如果該實(shí)例不存在的情況下,可以通過一個(gè)方法創(chuàng)建一個(gè)類來實(shí)現(xiàn)創(chuàng)建類的新實(shí)例,如果實(shí)例已經(jīng)存在,它會簡單返回該對象的引用。適用場景需要頻繁實(shí)例化然后銷毀的對象。頻繁訪問數(shù)據(jù)庫或文件的對象。 定義 限制類的實(shí)例化次數(shù)只能是一次。 如果該實(shí)例不存在的情況下,可以通過一個(gè)方法創(chuàng)建一個(gè)類來實(shí)現(xiàn)創(chuàng)建類的新實(shí)例,如果實(shí)例已經(jīng)存在,它會簡單返回該對象的引用。 適用場景 ...
摘要:添加獲取長度獲取下標(biāo)通知首先我們聲明一個(gè)主體類,里面包含一個(gè)觀察者數(shù)組,還有一些操作方法。觀察者通用聲明一個(gè)更新接口,用來獲取主體分發(fā)的通知。主體分發(fā)消息給觀察者。 觀察者模式 The Observer is a design pattern where an object (known as a subject) maintains a list of objects dependi...
摘要:概念模式就是一些提供能夠被一個(gè)或者一組子類簡單繼承功能的類意在重用其功能。示例下面通過一個(gè)簡單的例子來演示這個(gè)模式混入模式的實(shí)現(xiàn)不指定特定方法名的時(shí)候,將后者所有的方法都添加到前者里優(yōu)缺點(diǎn)優(yōu)點(diǎn)有助于減少系統(tǒng)中的重復(fù)功能及增加函數(shù)復(fù)用。 概念 Mixin模式就是一些提供能夠被一個(gè)或者一組子類簡單繼承功能的類,意在重用其功能。在面向?qū)ο蟮恼Z言中,我們會通過接口繼承的方式來實(shí)現(xiàn)功能的復(fù)用。但...
閱讀 1325·2021-10-27 14:14
閱讀 3579·2021-09-29 09:34
閱讀 2481·2019-08-30 15:44
閱讀 1728·2019-08-29 17:13
閱讀 2576·2019-08-29 13:07
閱讀 874·2019-08-26 18:26
閱讀 3349·2019-08-26 13:44
閱讀 3214·2019-08-26 13:37