javascript設計模式觀察者模式

admin發表於2017-04-16

觀察者模式主要應用於物件之間一對多的依賴關係,當一個物件發生改變時,多個對該物件有依賴的其他物件也會跟著做出相應改變,這就非常適合用觀察者模式來實現。使用觀察者模式可以根據需要增加或刪除物件,解決一對多物件間的耦合關係,使程式更易於擴充套件和維護。

基礎知識:

觀察者模式定義了物件間的一種一對多依賴關係,每當一個物件發生改變時,其相關依賴物件皆得到通知並被進行相應的改變。觀察者模式又叫做釋出-訂閱模式。生活中有很多類似的關係,比如微信公眾號訂閱,多個讀者訂閱一個微信公眾號,一旦公眾號有更新,多個讀者都會收到更新,而這種情況在應用程式中也非常常見,js繫結各種事件本質上就是觀察者模式的實現。

觀察者模式是一個非常有用的設計模式,它主要有兩個角色組成:

(1)目標物件:作為一對多關係中的一,可以用來管理觀察者的增加和刪除。

(2)觀察者物件:觀察目標物件,一旦目標發生改變則做出相應的反應。

觀察者模式的實現:

基本示例:

在Web開發中,我們經常遇到這種情況,ajax請求資料後,要同時更新資料到頁面的不同部分中,這種情況我們可以最直接的在ajax的回撥中更新頁面,但是如果要更新的位置很多,我們就要去修改回撥函式,這樣程式碼的維護性和擴張性不高,這種情況下,我們就可以用觀察者模式來實現。

首先,需要一個最基本的目標物件,我們定義如下:

[JavaScript] 純文字檢視 複製程式碼
function Subject() {
  this.observers = [];
}
Subject.prototype = {
  constructor: Subject,
  subscribe: function (fn) {
    this.observers.push(fn);
    return this;
  },
  unsubscribe: function (fn) {
    this.observers = this.observers.filter(function (item) {
      if (item !== fn) {
        return item;
      }
    });
    return this;
  },
  fire: function (data, context) {
    this.observers.forEach(function (item) {
      item.call(context, data);
    });
    return this;
  }
};

目標物件Subject中有一個陣列,這個陣列儲存觀察者列表,而目標物件提供三個方法:觀察物件,取消觀察物件,觸發物件更新。

我們通過subscribe方法增加觀察者,儲存到observers陣列中,如果有需要可以通過unsubscribe方法取消訂閱,然後更新資料時呼叫fire方法觸發,從而通知各個觀察者進行相應處理。

假設我們頁面有一個主檢視和一個側檢視,兩個檢視都要進行相應的修改,我們可以定義兩個物件如下:

[JavaScript] 純文字檢視 複製程式碼
function SideView() { }
SideView.prototype.render = function (data) {
  console.log("Side data:" + data);
}
function MainView() { }
MainView.prototype.render = function (data) {
  console.log("MainView data:" + data);
}

上面程式碼定義了兩個物件,分別為側檢視和主檢視,兩個物件都有相應的渲染頁面的方法render,然後我們將兩個方法新增到觀察者列表中。

[JavaScript] 純文字檢視 複製程式碼
var subject = new Subject();
var sideView = new SideView();
var mainView = new MainView();
 
subject.subscribe(sideView.render)
subject.subscribe(mainView.render);
subject.fire("test");

通過呼叫fire方法,傳入“test”,從而觸發兩個render函式。從這段程式碼中,我們可以很輕鬆地通過subscribe來新增觀察者物件,而不必每次都去修改fire方法。

jQuery中的觀察者模式:

jQuery中實現觀察者模式非常方便,簡短的幾句程式碼就可以實現

[JavaScript] 純文字檢視 複製程式碼
(function ($) {
  var obj = $({});
  $.subscribe = function () {
    obj.on.apply(obj, arguments);
  }
  $.unsubscribe = function () {
    obj.off.apply(obj, arguments);
  }
  $.fire = function () {
    obj.trigger.apply(obj, arguments);
  }
})(jQuery);

在jQuery中,通過on方法來繫結事件,off來移除事件,trigger來觸發事件,本質上就是一種觀察者模式。上面程式碼中,我們通過一個obj物件來儲存觀察者物件,我們只要像平時繫結事件一樣使用就可以,如下:

[JavaScript] 純文字檢視 複製程式碼
$.subscribe("render", function () {
  console.log("test");
})
$.subscribe("render", function () {
  console.log("test2");
})
$.fire("render");

這段程式碼分別輸出test和test2.我們繫結了兩個處理函式到render上,然後通過fire觸發render事件,這就實現了觀察者模式一對多依賴的特點。

總結:

觀察者模式是一種很常用的設計模式,因為我們的應用程式中涉及到依賴關係的非常多。常見的比如訊息通知,向使用者傳送一個訊息需要同時通知到站內信,郵件,簡訊等多種訊息,這種一對多的情況非常適合使用觀察者模式來實現。使用觀察者模式的關鍵是在於理清目標物件和觀察者物件,目標物件通過一個陣列對觀察者物件進行管理,更新資料的時候再迴圈呼叫觀察者物件,從而實現觀察者模式。

相關文章