5.Observer模式
(1)概念
使用Observer模式的目的是为了定义对象之间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并且自动更新。在以下情况下,一般可以考虑使用Observer模式。
·当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这二者封装在独立的对象中以便使它们可以各自独立地改变和复用。
·当对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象有待改变。
·当一个对象必须通知其他对象,而它又不能假定其他对象是谁。换言之,你不希望这些对象是紧密耦合的。
(2)举例
下面,我们将应用Observer模式实现简单的JavaScript事件处理机制。首先需要做一些准备工作,即对Array对象进行扩展,为其增加indexOf和removeAt方法,代码如下:
Object.extend=function(destination,source){
for(property in source){
destination[property]=source[property];
}
return destination;
}
//扩展Array对象的属性
Object.extend(Array.prototype,{
//在数组中查找object对象
indexOf: function (object){
for(var i=0,1ength=this.length; i<length; i++)
if(this[i]==object) return i;
return -1;
},
//将数组中指定位置的元素删除
removeAt: function (index){
if(index<0 || index>=this.length) return null;
switch(index){
case 0:
return this.shift();
break;
case this.length -1:
return this.pop();
break;
default:
var head=this.s1ice(0,index);
var tail=this.s1ice(index+1);
var ele=this[index];
this=head.concat(tail);
return ele;
break;
}
}
});
接下来,定义Observer类和Subject类。其中,Observer类的代码如下所示:
function Observer(){}
object.extend(Observer.prototype, {
//实体Observer类需要覆盖Update方法
Update:function(){
return;
}
});
Subject类的代码如下:
function Subject(){}
Object.extend(Subject.prototype,{
//Observer对象的数组
observers:[],
//通知每一个Observer对象执行Update方法
notify:function(context){
for(var i=0; i<this.observers.length; i++)
this.observers[i].Update(context);
},
//添加一个新的Observer
addObserver:function(observer) {
if(!observer.Update)
throw new Error(“addObserver error!”);
this.observers.push(observer);
},
//删除已有的Observer
removeObserver:function(Observer) {
if(!observer.Update)
throw new Error(“removeObserver error!”);
this.observers.removeAt(this.observers.indexOf(observer));
},
});
到此为止,使用Observer模式所需要的类都已经实现。下面是使用这些类实现Observer模式的步骤:
·创建Subject对象实例;
·创建若干个Observer对象实例,分别覆盖它们的Update方法;
·将Observer对象实例订阅到Subject对象上;
·通过Subject对象发出通知,此时所有订阅了该Subject对象的Observer对象均会执行各自的Update方法;
·如果需要撤销某个Observer对象对Subject对象的订阅,可以调用removeObserver方法实现。
最后,我们通过一个实例来演示Observer模式的应用。首先,创建一个Subject对象并且为该对象定义publishEvent方法。