一个对象(subject)维持一系列依赖于它(观察者)的对象,将有关状态的任何变更自动通知给它们。
当一个目标需要告诉观察者发生了什么有趣的事情,它会向观察者广播一个通知
当我们不再希望某个特定的观察者获取其注册目标发出的改变通知时,该目标可以将它从观察者列表中删除。
Observer(观察者)模式列表组件
Subject(目标): 维护一系列观察者,方便添加或删除观察者
Observer(观察者): 为那些在目标状态发生改变时需获得通知的对象提供一个更新接口
ConcreteSubject(具体目标):状态发生改变时,向Observer发出通知,存储ConcreteObserver的状态
ConcreteObserver(具体观察者):存储一个指向ConcreteSubject的更新接口,实现Observer的更新接口,以使自身状态与目标的状态保持一致。
1. 观察者模式的实现
1.1 模拟拥有的一系列依赖Observer
function ObserverList(){
this.observerList = [];
}
ObserverList.prototype.Add = function(obj){
return this.observerList.push(obj);
};
ObserverList.prototype.Remove = function(obj){
return this.observerList.pop(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.RemoveIndexAt = function(index){
if(index === 0){
this.observerList.shift();
}else if(index === this.observerList.length - 1){
this.observerList.pop();
}
};
//使用extension扩展对象
function extend(obj,extension){
for(var key in obj){
extension[key] = obj[key];
}
};
var liuyidi = {};
var observer = new ObserverList();
extend(observer,liuyidi);
console.log(liuyidi);
1.2 模拟目标(Subject)和在观察者列表上添加、删除或通知观察者
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);
}
};