天天看點

JavaScript 設計模式-觀察者模式

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

基礎知識:

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

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

(1)目标對象: 作為一對多關系中的一,可以用來管理觀察者的增加和删除。

(2)觀察者對象:觀察目标對象,一旦目标發生該表則做出相應的反應。

觀察者模式的實作:

基本示例:

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

首先,需要一個最基本的目标對象,我們定義如下

<script type="text/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)
            })
        }
    }
</script>      

目标對象Subject 中有一數組,這個數組儲存觀察者清單,而目标對象提供三個方法:觀察對象,取消觀察對象,觸發對象更新。

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

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

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,然後我們将兩個方法添加到觀察者清單中

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中實作觀察者模式非常友善,簡短的幾句代碼就可以實作

(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對象來儲存觀察者對象,我們隻要像平時綁定事件一樣使用就可以,如下。

$.subscribe("render",function(){
    console.log("test");
});

$.subscribe("render", function(){
    console.log("test2");
})

$.fire("render")      

// 這段代碼分别輸出test和test2.我們綁定了兩個處理函數到render上,然後通過fire觸發render事件,這就實作了觀察者模式一堆多一欄的特點

// 總結: 觀察者模式是一種很常用的設計模式,因為我們的應用程式中涉及到依賴關系的非常多。常見的比如消息通知,向使用者發送一個消息需要同時通知到站内信,郵件,短信等多種消息,這種一對多的情況非常适合使用觀察者模式來實作。使用觀察者模式的關鍵是在于理清目标對象和觀察者對象,目标對象通過一個數組對觀察者對象進行管理,更新資料的時候再循環調用觀察者對象,進而實作觀察者模式。

轉載于:https://www.cnblogs.com/ron123/p/8686957.html

繼續閱讀