觀察者模式:定義一對多的關系,讓多個觀察對象同時監聽某一個主題對象,主題對象狀態發生變化就通知所有觀察者對象。所以它是由兩類對像組成: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模式是同步,例如事件觸發,而發布-訂閱者使用的消息隊列模式,大多數處理異步事件。
【完】