標籤:listen 內容 span apply 通知 publish 實踐 提取 觀察者模式
觀察者模式又叫發布訂閱模式(Publish/Subscribe),它定義了一種一對多的關係,讓多個觀察者對象同時監聽某一個主題對象,這個主題對象的狀態發生變化時就會通知所有的觀察者對象,使得它們能夠自動更新自己。
舉個例子,我來公司面試的時候,完事之後每個面試官都會對我說:“請留下你的連絡方式, 有訊息我們會通知你”。 在這裡“我”是訂閱者, 面試官是發行者。所以我不用每天或者每小時都去詢問面試結果, 通訊的主動權掌握在了面試官手上。而我只需要提供一個連絡方式。
在Js中,DOM事件實際上就是一個觀察者模式。
document.body.addEventListener(‘click‘,function(){ ... },false);
我們並不知道使用者什麼時候會點擊body,所以註冊了一個這樣的事件,當body被點擊時,body節點就會向訂閱者發布這個訊息。
除此之外,還可以隨意的增加訂閱者和刪除訂閱者:
document.body.addEventListener(‘click‘,function(){ console.log(1) },false); document.body.addEventListener(‘click‘,function(){ console.log(2) },false); document.body.addEventListener(‘click‘,function(){ console.log(3) },false);
基於上面的面試例子,可以由以下的代碼來表現:
面試者把簡曆扔到一個盒子裡, 然後面試官在合適的時機拿著盒子裡的簡曆挨個打電話通知結果.
Events = function() { var listen, log, obj, one, remove, trigger, __this; obj = {}; __this = this; listen = function( key, eventfn ) { //把簡曆扔盒子, key就是連絡方式. var stack, _ref; //stack是盒子 stack = ( _ref = obj[key] ) != null ? _ref : obj[ key ] = []; return stack.push( eventfn ); }; one = function( key, eventfn ) { remove( key ); return listen( key, eventfn ); }; remove = function( key ) { var _ref; return ( _ref = obj[key] ) != null ? _ref.length = 0 : void 0; }; trigger = function() { //面試官打電話通知面試者 var fn, stack, _i, _len, _ref, key; key = Array.prototype.shift.call( arguments ); stack = ( _ref = obj[ key ] ) != null ? _ref : obj[ key ] = []; for ( _i = 0, _len = stack.length; _i < _len; _i++ ) { fn = stack[ _i ]; if ( fn.apply( __this, arguments ) === false) { return false; } } return { listen: listen, one: one, remove: remove, trigger: trigger } }
觀察者的使用場合就是:當一個對象的改變需要同時改變其它對象,並且它不知道具體有多少對象需要改變的時候,就應該考慮使用觀察者模式。
在Backbone架構中,事件的change機制就是一個觀察者模式,當使用者改變了某個屬性時,會調用trigger事件來依次通知訂閱者觸發事件。
設計模式系列基本是參考JavaScript設計模式與開發實踐一書的內容,提取裡面的綱要方便學習。
JavaScript設計模式 觀察者模式