观察者模式(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模式是同步,例如事件触发,而发布-订阅者使用的消息队列模式,大多数处理异步事件。

【完】

如来者,无所从来,亦无所去,故名如来。
                                                                 ——鸠摩罗什 《金刚经》
posted @ 2018-11-23 14:48  tangjiao_Miya  阅读(3137)  评论(0编辑  收藏  举报