1. 程式人生 > >javscript-發布訂閱模式與觀察者模式

javscript-發布訂閱模式與觀察者模式

splice reac 解決方法 狀態 square n) 方法 vsc 模式

設計模式”(Design Pattern)是針對編程中經常出現的、具有共性的問題,所提出的解決方法。著名的《設計模式》一書一共提出了23種模式。

發布訂閱模式

它定義了一種對象間一對多的關系,多個訂閱者對象將自己的“主題/事件”註冊進一個目標對象,當目標對象狀態發生改變時,只需要去執行對應訂閱者註冊的 "主題/事件" 就行了。這是一種松耦合的狀態。目標對象不用關心任何訂閱者的情況, 只需要發布註冊在自己身上的事件就行了。
訂閱者只管註冊 目標對象只管發布 互不影響
代碼實現:

let event = {
    clientList: {},
    listen (key, fn) {
        if (!this.clientList[key]) {
            this.clientList[key] = []
        }
        this.clientList[key].push(fn)   // 訂閱的消息添加進緩存列表
    },
    trigger (type, money) {
        let fns = this.clientList[type]
        if (!fns || fns.length === 0) { // 如果沒有綁定對應的消息
            return false
        }
        fns.forEach(fn => {
            fn.apply(this, [money])
        })
    }
}
// 再定義一個installEvent函數,用於給所有對象動態安裝發布-訂閱功能
// 如:另一家售樓處也想要這個功能,就可以調用這個註冊了,不用再寫多一次這段代碼
let installEvent = obj => {
    for (let i in event) {
        obj[i] = event[i]
    }
}
// 給售樓處對象salesOffices動態增加發布-訂閱功能
let salesOffices = {}
installEvent(salesOffices)
// 小明訂閱信息
salesOffices.listen('squareMeter88', price => {
    console.log('小明,你看中的88平方的房子,價格=' + price)
})
// 小光訂閱信息
salesOffices.listen('squareMeter88', price => {
    console.log('小光,你看中的88平方的房子,價格=' + price)
})
// 小紅訂閱信息
salesOffices.listen('squareMeter100', price => {
    console.log('小紅,你看中的100平方的房子,價格=' + price)
})
salesOffices.trigger('squareMeter88', 2000000)
salesOffices.trigger('squareMeter100', 2500000)

觀察者模式

觀察者模式與發布訂閱最大的區別是訂閱者註冊的是自己本身,不再是註冊 “主題/事件”,當目標對象狀態發生改變時,會調用自身的通知方法,從而調用註冊在自身的訂閱者的更新方法。

//觀察者列表
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 );
};

//目標
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(){
  this.update = function(){
    // ...
  };
}

區別:

發布訂閱模式實現了更細粒度化的管理,觀察者模式當目標對象狀態變化時會通知所有訂閱者,而發布訂閱則會通過調度中心執行具體的訂閱者註冊的 "主題/事件",發布訂閱更松耦合一些。

javscript-發布訂閱模式與觀察者模式