JavaScript 中介者模式與觀察者模式有何不一樣?

http://addyosmani.com/resources/essentialjsdesignpatterns/book/#detailmvpjavascript

感受兩者很是像,都是pub/sub機制,如何進行區分?分別在什麼不一樣的場景中進行應用?

  • 在Obsever模式中, 不存在封裝約束的單一對象。Observer 和 Subject 必須合做才能維持約束。
  • Communication(通信)模式由觀察者和目標互聯的方式決定:單一目標一般有不少觀察者,有時一個目標的觀察者是另外一個觀察者的目標
  • Mediator 和 Observer  都能促進鬆耦合,而後Mediator 模式經過限制對象嚴格經過Mediator 進行通訊來實現這個個目的
  • Observer 模式建立觀察者對喜好那個,觀察者對象向訂閱它們的對喜好那個發佈其感興趣的事件。

在GoF的原文中是這樣描述觀察者模式的:

  • One or more observers are interested in the state of a subject and register their interest with the subject by attaching themselves. When something changes in our subject that the observer may be interested in, a notify message is sent which calls the update method in each observer. When the observer is no longer interested in the subject's state, they can simply detach themselves.
  • 具體應用場景是,當subject的某個動做須要引起一系列不一樣對象的動做(好比你是一個班長要去通知班裏的某些人),與其一個一個的手動調用觸發的方法(私下裏一個一個通知),不如維護一個列表(建一個羣),這個列表存有你想要調用的對象方法(想要通知的人);以後每次作的觸發的時候只要輪詢這個列表就行了(羣發),而不用關心這個列表裏有誰,只用關心想讓誰加入讓誰退出


這個列表就叫作ObserverList,它有一些維護列表方法:html

function ObserverList(){
  this.observerList = [];
}
ObserverList.prototype.Add = function( obj ){};
ObserverList.prototype.Empty = function(){};
ObserverList.prototype.Count = function(){};
ObserverList.prototype.Get = function( index ){};
ObserverList.prototype.Insert = function( obj, index ){};
ObserverList.prototype.IndexOf = function( obj, startIndex ){};
ObserverList.prototype.RemoveAt = function( index ){};

而咱們的subject只用關心兩件事:1.維護這個列表,2.發佈事件java

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 );  
    // 在這裏假設的是列表裏的每一個對象都有update方法,但我的以爲這個列表裏也能夠是不一樣對象的不一樣方法,只要能接受當前上下文做爲參數, 能夠這樣執行:
    // subscription.callback.apply( subscription.context, args );
  }
};

中介模式(Mediator Pattern)

讓咱們假設這樣一個場景: 有一個Manager一聲令下,須要讓工人A和工人B開工,代碼能夠是這樣的app

Manager.start = function () {
    A.work();
    B.work();
}

其實還能夠這麼寫,新增一箇中介模塊,這個模塊有存儲了Manager的經常使用命令好比start,stop,resume,每個命令其實維護的也是一個列表,好比start的列表下存儲了全部員工的start方法:異步

Mediator["start"] = [
    {
        name: 'A',
        callback: 'work'
    },
    {
        name: 'B',
        callback: 'workAgain'
    },
]

因此Manager的方法能夠重寫爲模塊化

Manager.start = function () {
    Mediator.publish('start')   // publish 爲觸發命令函數,以此來觸發start命令下維護的全部回調函數
}

代碼細節就不展現了,主要體現這麼一個機制,而若是某個員工要提交本身的work方法供老闆調用的話,只要註冊一下就行了函數

Mediator.subscribe('C', function callback() {});

 

問題是新增長一箇中介模塊的好處是什麼?

1.低耦合!若是不是經理要讓員工開始工做,是董事長怎麼辦,或者是部門主管怎麼辦,難道都要這麼寫this

XXX.start = function () {
    A.work()
    B.work();
}

都要把A.work什麼抄一遍?固然不是,只要給中介模塊發出命令就行了,
2.模塊之間不須要進行通訊,只要負責廣播和監聽事件就行了
3.在模塊化的javascript中,中介模塊能提升可維護性:是否啓動某個模塊,有沒有權限啓動某個模塊,異步加載某些模塊,模塊之間的依賴關係,某些模塊啓動失敗了怎麼辦。這些邊界條件均可以交給它來判斷,而其餘模塊只關心實現本身邏輯就行了
最後打個比方,中介模塊真的就像房屋中介同樣!若是你是房東,你只須要下令一聲「我要找人租房」,他們就天然會生成那個列表,你不用直接和房客打交道。prototype

相關文章
相關標籤/搜索