觀察者模式(Observer)和發布-訂閱者模式(Publish/Subscribe)區別


觀察者模式:定義一對多的關系,讓多個觀察對象同時監聽某一個主題對象,主題對象狀態發生變化就通知所有觀察者對象。所以它是由兩類對像組成:Subject主題+Observer觀察者。主題發布事件,觀察者通過訂閱事件觀察主題。

Observer模式提供給關聯對象一種同步通信的手段,使得主題和觀察者之間保持同步通信 

function observar(oldVal,newVal){
    console.log(`name屬性值從${oldVal}改變為${newVal}`);
}
class TargetObj{
    constructor(age,name){
        this.name = name;
        this.age = age;
    }
    set name(val){ observar(name,val); name = val; }
}
let targetObj = new TargetObj(22,'miya');
targetObj.name = 'Lily';
console.log(targetObj)
//name屬性值從改變為miya
//name屬性值從miya改變為Lily 

阮一峰大神在介紹Reflect時候,使用Proxy寫了一個觀察者模式的代碼:

//觀察者隊列
const queuedObservers = new Set();
const observe = fn => queuedObservers.add(fn);
function print(){
    console.log(`${person.name},${person.age}`);
}
//將觀察者放入隊列中
observe(print);
const person = new Proxy({name:'張三',age:22},{
    set(target,key,value,receiver){
        const result = Reflect.set(target,key,value,receiver); queuedObservers.forEach(observer => observer()); return result;
    }
}) 
person.name = '李四';
//李四,22

上面代碼可以看出,觀察者模式是:Observer在Subject主題對象特定活動狀態改變時候獲取通知。主題Subject需要一個數組類型來存儲所有的訂閱者。Subject和Observer之間存在依賴關系,存在耦合。 

JavaScript中的事件監聽機制可以理解為觀察者模式,通過onclick事件綁定,然后事件主動觸發。

發布—訂閱模式:完全解耦,發布者和訂閱者彼此不知道對方的存在,二者共享一個自定義事件的名稱。它的優點非常明顯,一為時間上的解耦,二為對象之間的解耦。

觀察者模式中,目標對象也就是Subject管理觀察者,發布-訂閱模式中多了一個中間層通道。 

//發布-訂閱
var Event = (function(){
    var clientList = {},
    listen,
    trigger,
    remove;
    listen = function(key,fn){
        if(!clientList[key]){
            clientList[key] = [];            
        }
        clientList[key].push(fn);
    }
    trigger = function(){
        var key = Array.prototype.shift.call(arguments),
        fns = clientList[key];
        if(!fns ||  fns.length === 0){
            return false;
        }
        for(var i = 0,fn;fn = fns[i++];){
            fn.apply(this,arguments);
        }
    }
    remove = function(key,fn){
         var fns = clientList[key];
         if(!fns) return false;
         if(!fn){
             fns && (fns.length = 0);
         }else{
             for(var i = 0,_fn;_fn = fns[i++];){
                 if(fn === _fn){
                     fns.splice(i,1);
                 }
             }
         }
    }
    return {
        listen:listen,
        trigger:trigger,
        remove:remove
    }
})()
Event.listen('LondonAirPlay',function(price){
    console.log(`the price is ${price}`)
})
Event.trigger('LondonAirPlay',3000)
//the price is 3000 

訂閱者想要訂閱倫敦的機票,通過Event對象來實現了,Event對象具有listen訂閱,trigger發布,remove取消等功能,訂閱者和發布者之間完全是不認識的,Event類似於一個“中介者”,將訂閱者和發布者聯系起來。 

 

總結:

1,Observer模式,觀察者是知道Subject主題的,目標主題一直保持對觀察者的記錄,而publish-subscribe模式中,訂閱者和發布者互相不知道對方,通過消息代理進行通信。

2,Observer模式中,觀察者和主題之間存在依賴耦合關系,而發布訂閱者模式則完全松耦合的。

3,多數情況下,Observer模式是同步,例如事件觸發,而發布-訂閱者使用的消息隊列模式,大多數處理異步事件。

【完】

如來者,無所從來,亦無所去,故名如來。
                                                                 ——鳩摩羅什 《金剛經》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM