觀察者模式的一個例子
觀察者模式(有時又被稱為發布-訂閱模式、模型-視圖模式、源-收聽者
觀察者模式(Observer)完美的將觀察者和被觀察的對象分離開。舉個例子,用戶界面可以作為一個觀察者,業務數據是被觀察者,用戶界面觀察業務數據的變化,發現數據變化后,就顯示在界面上。面向對象設計的一個原則是:系統中的每個類將重點放在某一個功能上,而不是其他方面。一個對象只做一件事情,并且將他做好。觀察者模式在模塊之間劃定了清晰的界限,提高了應用程序的可維護性和重用性。
下面,我是在他人基礎上做的一個封裝以及簡單繼承。
<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"/> </head> <body> <button id="sendWeekly">發送周報</button> <button id="sendDaily">發送日報</button> <script> var inherits = function (ctor, superCtor) { // 顯式的指定父類 ctor.super_ = superCtor; superCtor = typeof superCtor === "function" ? superCtor.prototype : superCtor; // ECMAScript 5 原型式繼承并解除引用 if (Object.create) { ctor.prototype = Object.create(superCtor, { constructor:{ value:ctor, enumerable:false, writable:true, configurable:true } }); } else { // 無Object.create方法的平穩退化 function F() { }; F.prototype = superCtor; ctor.prototype = new F(); ctor.prototype.constructor = ctor; } }; var Observer = (function (W) { var pubsub = function () { this.topics = {}; this.subUid = -1; }; // 發布方法 pubsub.prototype.fire = function (type) { var args = [].slice.call(arguments, 1), that = this; if (!this.topics[type]) { return false; } (function () { var subscribers = that.topics[type], len = subscribers ? subscribers.length : 0; while (len--) { subscribers[len].func.apply(that, args); } })(); return true; }; //訂閱方法 pubsub.prototype.on = function (type, fn) { if (!this.topics[type]) { this.topics[type] = []; } var token = (++this.subUid).toString(); this.topics[type].push({ token:token, func:fn }); return token; }; //退訂方法 pubsub.prototype.off = function (type, token) { var evT; if (type === void 0) { return this.topics = {} } if (arguments.length == 1) { if (!this.topics[type]) { return; } return delete this.topics[type]; } evT = this.topics[type]; for (var i = 0, j = evT.length; i < j; i++) { if (evT[i].token === token) { evT.splice(i, 1); return token; } } return false; }; return pubsub; }(window)); function Paper(name, pages, price) { this.name = name; this.pages = pages; this.price = price; } inherits(Paper, new Observer); Paper.prototype.send = function (topic) { this.fire(topic, { name:this.name, pages:this.pages, price:this.price }); }; function Person(name) { var that = this; this.name = name; this.recive = function (paper) { console.log(that.name + ' recive Pager detail:\n' + 'name:' + paper.name + '\npages:' + paper.pages + '\nprice:' + paper.price) } } var person = new Person('Lucy'), person1 = new Person('Tom'); var Weekly = new Paper('weekly', 298, '$6'), Daily = new Paper('daily', 7, '$0.8'); var pr = Weekly.on('weekly', person.recive), pr1 = Weekly.on('weekly', person1.recive); var pr2 = Daily.on('daily', person.recive); var $ = function (id) { return document.getElementById(id); } $('sendWeekly').onclick = function () { Weekly.send('weekly'); } $('sendDaily').onclick = function () { Daily.send('daily'); } </script> </body> </html>

浙公網安備 33010602011771號