/* * js 觀察者模式 又稱 訂閱/發佈模式 * 經過建立「可觀察」對象,當發生一個感興趣的事件時可將該事件通告給 * 全部觀察者,從而造成鬆耦合 */ // 通用的發佈者 EventPublisher = Base.extend({ publish: function(data, type) { EventPublisher.publish(data, type); } }, { subscribers : { any : [] // 事件類型: 訂閱者 }, // 將訂閱者提供的調用方法添加到subscribers 訂閱的事件數組中 subscribe : function(subscriber) { var type = subscriber.type || 'any'; if (typeof this.subscribers[type] === 'undefined') { this.subscribers[type] = []; } this.subscribers[type].push(subscriber.handleEvent); }, // 刪除訂閱者 unsubscribe : function(fn, type) { this.visitSubscribers('unsubscribe', fn, type); }, // 循環遍歷subscribers中每一個元素,並調用他們所提供的方法 publish : function(publication, type) { this.visitSubscribers('publish', publication, type); }, // helper visitSubscribers: function (action, arg, type) { var pubtype = type || 'any', subscribers = this.subscribers[pubtype], i, max = subscribers.length; for (i = 0; i < max; i += 1) { if (action === 'publish') { // 調用訂閱者訂閱該事件所提供的方法 subscribers[i](arg); } else { // 找到當前訂閱事件中提供的方法,並刪除 if (subscribers[i] === arg) { subscribers.splice(i, 1); } } } } });
// 實現paper 對象,他所作的就是發佈日刊和月刊 Paper = EventPublisher.extend({ daily : function() { this.publish('今個有重要新聞', 'paper-daily'); }, monthly : function() { this.publish('每個月調查', 'paper-monthly'); }, readWeibo: function(info) { console.log('重大新聞[' + info + ']'); } }); // 訂閱者對象joe,該對象有2個方法 Person = EventPublisher.extend({ name: null, constructor: function(config) { this.name = config.name; }, drinkCoffee : function(paper) { console.log(this.name + '開始閱讀[' + paper + ']'); }, sundayPreNap : function(monthly) { console.log(this.name + '開始閱讀[' + monthly + ']'); }, weibo: function(msg) { this.publish(msg, 'person-weibo'); } }); var paper = new Paper(); var darkness = new Person({ name: 'darkness' }); EventPublisher.subscribe({ type: 'paper-monthly', handleEvent: function(data) { darkness.sundayPreNap(data); } }); EventPublisher.subscribe({ type: 'paper-daily', handleEvent: function(data) { darkness.drinkCoffee(data); } }); EventPublisher.subscribe({ type: 'person-weibo', handleEvent: function(data) { paper.readWeibo(data); } }); // paper開始發佈日刊 和 月刊 paper.daily(); paper.monthly(); // darkness發佈微博信息 darkness.weibo('今日頭條,2015年啦!');
一個javascript繼承的基礎類Base.jsjavascript