观察者模式(有时又被称为发布(publish )-订阅(Subscribe)模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。
基本简介
观察者模式(Observer)完美的将观察者和被观察的对象分离开。举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。面向对象设计的一个原则是:系统中的每个类将重点放在某一个功能上,而不是其他方面。一个对象只做一件事情,并且将他做好。观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。
观察者设计模式定义了对象间的一种一对多的依赖关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。
由于观察者模式有诸多优点,他在日常编程中随处可见,比如响应事件,作为一名程序猿,掌握他是义不容辞的责任。
代码实现
function subject() { if (!(this instanceof subject)) { return new subject(); } this._eventList = {};}subject.prototype = { /** * 注册观察者 * @param {string} eName [注册的事件名称] * @param {Function} fn [响应事件的方法] * @param {object} [scope] [响应事件的方法的上下文对象] */ on: function(eName, fn, scope) { if (!eName == null) return; if (Object.prototype.toString.call(fn) === '[object Function]') { eName = eName.toLowerCase(); if (!this._eventList[eName]) { this._eventList[eName] = []; } this._eventList[eName].push({ fn: fn, scope: scope || null }); } }, /** * 注销观察者 * 取消指定方法对指定事件的响应 * 如果事件为空,注销所有事件的响应 * 如果方法为空,注销指定事件的所有响应方法 * @param {string} [eName] [注销的事件名称,] * @param {Function} [fn] [注销的响应事件的方法] */ off: function(eName, fn) { if (eName == null) { this._eventList = {}; } else if (fn == null) { delete this._eventList[eName] } else { var fns = this._eventList[eName]; if (fns && fns.length) { for (var l = fns.length; l--;) { if (fns[l] == fn) { fns.slice(l, 1); break; } } } } }, /** * 发布订阅事件 * @param {string} eName [事件名称] * @param {object} [args] [事件参数] */ fire: function() { var args = Array.prototype.slice.call(arguments); var eName = args.shift(); if (!eName) return; eName = eName.toLowerCase(); var list = this._eventList[eName] || []; for (var i = 0, l = list.length; i < l; i++) { var dict = list[i]; var fn = dict.fn; var scope = dict.scope; fn.apply(scope || null, args); } }}