觀察者模式(有時又被稱爲發佈(publish )-訂閱(Subscribe)模式)是軟件設計模式的一種。在此種模式中,一個目標物件管理全部相依於它的觀察者物件,而且在它自己的狀態改變時主動發出通知。這一般透過呼叫各觀察者所提供的方法來實現。此種模式一般被用來實現事件處理系統。javascript
觀察者模式(Observer)完美的將觀察者和被觀察的對象分離開。舉個例子,用戶界面能夠做爲一個觀察者,業務數據是被觀察者,用戶界面觀察業務數據的變化,發現數據變化後,就顯示在界面上。面向對象設計的一個原則是:系統中的每一個類將重點放在某一個功能上,而不是其餘方面。一個對象只作一件事情,而且將他作好。觀察者模式在模塊之間劃定了清晰的界限,提升了應用程序的可維護性和重用性。java
觀察者設計模式定義了對象間的一種一對多的依賴關係,以便一個對象的狀態發生變化時,全部依賴於它的對象都獲得通知並自動刷新。編程
因爲觀察者模式有諸多優勢,他在平常編程中隨處可見,好比響應事件,做爲一名程序猿,掌握他是責無旁貸的責任。設計模式
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); } } }