观察者模式的一个例子
观察者模式(有时又被称为发布-订阅模式、模型-视图模式、源-收听者
观察者模式(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>