1、被观察者:维护一组观察者, 提供用于增加和移除观察者的方法。
2、观察者:提供一个更新接口,用于当被观察者状态变化时,得到通知。
3、具体的被观察者:状态变化时广播通知给观察者,保持具体的观察者的信息。
4、具体的观察者:保持一个指向具体被观察者的引用,实现一个更新接口,用于观察,以便保证自身状态总是和被观察者状态一致的。
接着,我们对被观察者以及其增加,删除,通知在观察者列表中的观察者的能力进行建模:
在这个例子里面,我们看到了如何实现和配置观察者模式,了解了被观察者,观察者,具体被观察者,具体观察者的概念。
2、观察者:提供一个更新接口,用于当被观察者状态变化时,得到通知。
3、具体的被观察者:状态变化时广播通知给观察者,保持具体的观察者的信息。
4、具体的观察者:保持一个指向具体被观察者的引用,实现一个更新接口,用于观察,以便保证自身状态总是和被观察者状态一致的。
首先,让我们对被观察者可能有的一组依赖其的观察者进行建模:
function ObserverList(){
this.observerList = [];
}
ObserverList.prototype.Add = function( obj ){
return this.observerList.push( obj );
};
ObserverList.prototype.Empty = function(){
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.RemoveAt = function( index ){
if( index === 0 ){
this.observerList.shift();
}else if( index === this.observerList.length -1 ){
this.observerList.pop();
}
};
// Extend an object with an extension
function extend( extension, obj ){
for ( var key in extension ){
obj[key] = extension[key];
}
}
接着,我们对被观察者以及其增加,删除,通知在观察者列表中的观察者的能力进行建模:
function Subject(){
this.observers = new ObserverList();
}
Subject.prototype.AddObserver = function( observer ){
this.observers.Add( observer );
};
Subject.prototype.RemoveObserver = function( observer ){
this.observers.RemoveAt( 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 );
}
};
我们接着定义建立新的观察者的一个框架。这里的update 函数之后会被具体的行为覆盖。
// The Observer
function Observer(){
this.Update = function(){
// ...
};
}
在我们的样例应用里面,我们使用上面的观察者组件,现在我们定义:
- 一个按钮,这个按钮用于增加新的充当观察者的选择框到页面上
- 一个控制用的选择框 , 充当一个被观察者,通知其它选择框是否应该被选中
- 一个容器,用于放置新的选择框
HTML:
<button id="addNewObserver">Add New Observer checkbox</button>
<input id="mainCheckbox" type="checkbox"/>
<div id="observersContainer"></div>
Sample script:
// 我们DOM 元素的引用
var controlCheckbox = document.getElementById( "mainCheckbox" ),
addBtn = document.getElementById( "addNewObserver" ),
container = document.getElementById( "observersContainer" );
// 具体的被观察者
//Subject 类扩展controlCheckbox 类
extend( new Subject(), controlCheckbox );
//点击checkbox 将会触发对观察者的通知
controlCheckbox["onclick"] = new Function( "controlCheckbox.Notify(controlCheckbox.checked)" );
addBtn["onclick"] = AddNewObserver;
// 具体的观察者
function AddNewObserver(){
//建立一个新的用于增加的checkbox
var check = document.createElement( "input" );
check.type = "checkbox";
// 使用Observer 类扩展checkbox
extend( new Observer(), check );
// 使用定制的Update函数重载
check.Update = function( value ){
this.checked = value;
};
// 增加新的观察者到我们主要的被观察者的观察者列表中
controlCheckbox.AddObserver( check );
// 将元素添加到容器的最后
container.appendChild( check );
}
在这个例子里面,我们看到了如何实现和配置观察者模式,了解了被观察者,观察者,具体被观察者,具体观察者的概念。
《学用 JavaScript 设计模式》学习资料来源,感谢各位专家们的翻译!
http://www.oschina.net/translate/learning-javascript-design-patterns