【讀書筆記】讀《JavaScript設計模式》之觀察者模式

1、定義程序員

  在事件驅動的環境中,好比瀏覽器這種持續尋求用戶關注的環境中,觀察者模式(又名發佈者-訂閱者(publisher-subscripber)模式)是一種管理人與其任務之間的關係(確切地講,是對象及其行爲和狀態之間的關係)的得力工具.用JavaScript的話來講,這種模式的實質就是你能夠對程序中某個對象的狀態進行觀察,而且在其發生改變時可以獲得通知。編程

2、例子數組

  咱們須要一個發佈者的構造函數,它爲該實例定義了一個類型爲數組的屬性,用來保存訂閱者的引用。瀏覽器

function Publisher() {
    this.subscribers = [];
}

  接下來,構建訂閱方法。全部Publisher實例都應該可以投送數據。只要把deliver方法添加到Publisher的prototype中,它就可以被全部Publisher對象共享。函數

// 訂閱者訂閱能力
Function.prototype.subscribe = function(publisher) {
    var that = this,
        alreadyExists = false,
        i,
        len = publisher.length;

    for(i = 0; i < len; i++) {
        if (el === this) {
            alreadyExists = true;
        }
    }

    if (!alreadyExists) {
        publisher.subscribers.push(this);
    }

    return this;
};

// 訂閱者具備退訂能力
Function.prototype.unSubscribe = function(publisher) {
    var that = this,
        array = [],
        len = publisher.length;

    for(i = 0; i < len; i++) {
        if (el !== this) {
            array.push(this);
        }
    }

    publisher.subscribers = array;

    return this;
};

  應用之——工具

// 訂閱者訂閱能力
Function.prototype.subscribe = function(publisher) {
    var that = this,
        alreadyExists = false,
        i,
        len = publisher.length;

    for(i = 0; i < len; i++) {
        if (el === this) {
            alreadyExists = true;
        }
    }

    if (!alreadyExists) {
        publisher.subscribers.push(this);
    }

    return this;
};

// 訂閱者具備退訂能力
Function.prototype.unSubscribe = function(publisher) {
    var that = this,
        array = [],
        len = publisher.length;

    for(i = 0; i < len; i++) {
        if (el !== this) {
            array.push(this);
        }
    }

    publisher.subscribers = array;

    return this;
};

3、現實世界中的觀察者性能

  在現實世界中,觀察者模式對於那種由許多JavaScript程序員合做開發的大型應用程序特別有用。它能夠提升API的靈活性,使並行開發的多個市縣可以彼此獨立的進行修改。做爲開發人員,你能夠對本身的應用程序中什麼是「使人感興趣的時刻」作出決定。你所能監聽的再也不只是click、load、blur和mouseover等瀏覽器事件。在富用戶界面應用程序中,drag(拖動)、drop(拖放)、moved(移動)、complete(完成)和tabSwitch(標籤切換)均可能是使人感興趣的事件。它們都是在普通瀏覽器事件的基礎上抽象出來的可觀察事件,可由發佈者對象向其監聽者廣播。this

  在DOM腳本編程環境中的高級時間模式中,事件監聽器說到底就是一種內置的觀察者。事件處理器(handler)與事件監聽器(listener)並非一回事。前者說穿了就是一種把事件傳遞給與其關聯的函數的手段。並且在這種模型中一種事件只能指定一個回調方法。而在監聽器模式中,一個事件能夠與幾個監聽器關聯。每一個監聽器都能獨立於其餘監聽器而改變。spa

// 使用事件監聽器,可讓多個函數響應同一個事件
var element = $('#example');
var fn1 = function(e) {
    // handle clikc
};
var fn2 = function(e) {
    // do other stuff with click
};
// 因爲使用的是事件監聽器,因此click事件發生時fn1和fn2都會被調用
addEvent(element, 'click', fn1);
addEvent(element, 'click', fn2);
// 但用事件處理器就辦不到
var element = $('#example');
var fn1 = function(e) {
    // handle clikc
};
var fn2 = function(e) {
    // do other stuff with click
};
element.onclick = fn1;
// 第二個onclick賦值的結果是fn1被fn2取代,所以click事件發生時只會調用fn2。
element.onclick = fn2;

  監聽器和觀察者之間的共同之處顯而易見。實際上它們互爲同義詞。它們都訂閱特定的事件,而後等待事件的發生。事件發生時,訂閱方的回調函數會獲得通知。傳給它們的參數是一個事件對象,其中包含着事件發生時間、事件類型和事件發源地等有用的信息。prototype

4、優點

  觀察者模式能夠削減爲事件註冊監聽器的次數,讓可觀察對象藉助一個事件監聽器替你處理各類行爲並將信息委託給它的全部訂閱者,從而下降內存消耗和提升互動性能,提升程序的可維護性。

5、劣勢

  使用這種觀察者接口的一個不利之處在於建立可觀察對象所帶來的加載時間開銷。這能夠經過惰性加載技術加以化解。

6、小結

  一個事件能夠被5個訂閱者訂閱,而一個訂閱者也能夠訂閱5個不一樣的事件。對於瀏覽器這類互動環境來講這很是理想。如今的Web應用程序愈來愈大,在此背景下,做爲一種提升代碼的可維護性和簡潔性的有力手段,可觀察對象的做用更顯突出。

相關文章
相關標籤/搜索