前言:Observer ( 观察者 ) 是一种设计模式,其中,一个对象( 称之为 subject )维持一系列依赖于它( 观察者 )的对象,将有关状态的任何变更自动通知给他们。
观察者模式的机制 一个或多个观察者对目标的状态感兴趣,他们通过将自己依附在目标对象上以便注册所感兴趣的内容。目标状态发生改变并且观察者可能对这些改变感兴趣,就会发送一个通知,调用每个观察者的更新方法。当观察者不再对目标状态感兴趣时,他们可以简单地将自己从中分离。
观察者模式的组成部分
Subject (目标):维护一系列的观察者,方便添加或删除观察者
Observer(观察者):为那些在目标状态发生改变时需要获得通知的对象提供一个更新接口
ConcreteSubject(具体目标):状态发生改变时,向 Observer 发出通知,储存 ConcreteObserver 的状态
ConcreteObserver(具体观察者):存储一个指向 ConcreteSubject 的引用,实现 Observer 的更新接口,以使自身状态与目标状态保持一致。
Observer 实现 首先,我们来具体实现观察者的 Observer 部分。下面我们将模拟一个目标可能拥有的一系列依赖 Observer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 function ObserverList () { this .observerList = []; } ObserverList.prototype.Add = function (obj) { return this .observerList.push(obj); }; ObserverList.prototype.Empty = function () { return this .observerList = []; }; ObserverList.prototype.Count = function () { return this .observerList.length; }; ObserverList.prototype.Get = function (index) { if (index > -1 && index < this .observerList.length) { return this .observerList[index]; } }; ObserverList.prototype.Insert = function (obj, index) { var pointer = -1 ; if (index === 0 ) { this .observerList.unshift(obj); pointer = index; } else if (index === this .observerList.length) { this .observerList.push(obj); pointer = index; } return pointer; }; ObserverList.prototype.IndexOf = function (obj, startIndex) { var i = startIndex, pointer = -1 ; while (i < this .observerList.length) { if (this .observerList[i] === obj) pointer = i; i++; } return pointer; }; ObserverList.prototype.removeIndexAt = function (index) { if (index === 0 ) { this .observerList.shift(); } else if (index === this .observerList.length - 1 ) { this .observerList.pop(); } }; function extend (obj, extension) { for (var key in obj) { extension[key] = obj[key]; } }
Subject 实现 接下来,我们模拟目标和在观察者列表上添加删除或通知观察者的能力
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 function Subject () { this .observers = new ObserverList(); } Subject.prototype.addObserver = function (observer) { this .observers.Add(observer); }; Subject.prototype.removeObserver = function (observer) { this .observers.removeIndexAt(this .observers.IndexOf(observer, 0 )); }; Subject.prototype.Notify = function (context) { var observerCount = this .observers.Count(); for (var i = 0 ; i < observerCount; i++) { this .observers.Get(i).Update(context); } };
观察者模式举例 描述:
添加一个目标 (subject) checkbox,通知其他 checkbox 进行检查
添加观察者 ( observer ) checkbox,用于接收目标 checkbox 发送的通知
具体代码 - html 部分 1 2 3 <button id="addNewObserver" >Add New Observer checkbox</button> <input type="checkbox" id="mainCheckbox" /> <div id="observersContainer" ></div>
具体代码 - Js 部分 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 cript type="text/javascript" > var controlCheckbox = document .getElementById("mainCheckbox" ); var addBtn = document .getElementById("addNewObserver" ); var container = document .getElementById("observersContainer" ); extend(new Subject(), controlCheckbox); controlCheckbox.onclick = new Function ("controlCheckbox.Notify(controlCheckbox.checked)" ); addBtn.onclick = AddNewObserver; function AddNewObserver ( ) { var check = document .createElement("input" ); check.type = "checkbox" ; extend(new Observer(), check); check.Update = function (value ) { this .checked = value; }; controlCheckbox.addObserver(check); container.appendChild(check); }
预览地址