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