JS实现观察者模式

前言:
今天跟向华交流,讨论到现有接处警系统客户端性能问题。提及到了观察者模式。开始对此不太了解,回家后在网上收集了一些资料,研究学习了2个小时左右。个人非常赞同华仔的向华,在我们指挥调度系统中的案件模块,尤其是客户端引入该模式十分必要。以下是学习中编写的代码:
基本概念:
       观察者模式(Observer)完美的将观察者和被观察的对象分离开。举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。面向对象设计的一个原则是:系统中的每个类将重点放在某一个功能上,而不是其他方面。一个对象只做一件事情,并且将他做好。观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。
  观察者模式有很多实现方式,从根本上说,该模式必须包含两个角色:观察者和被观察对象。在刚才的例子中,业务数据是被观察对象,用户界面是观察者。观察者和被观察者之间存在“观察”的逻辑关联,当被观察者发生改变的时候,观察者就会观察到这样的变化,并且做出相应的响应。如果在用户界面、业务数据之间使用这样的观察过程,可以确保界面和数据之间划清界限,假定应用程序的需求发生变化,需要修改界面的表现,只需要重新构建一个用户界面,业务数据不需要发生变化。
实现观察者模式有很多形式,比较直观的一种是使用一种“注册——通知——撤销注册”的形式。下面的三个图详细的描述了这样一种过程:
  1:观察者(Observer)将自己注册到被观察对象(Subject)中,被观察对象将观察者存放在一个容器(Container)里。
  2:被观察对象发生了某种变化(如图中的SomeChange),从容器中得到所有注册过的观察者,将变化通知观察者。
  3:观察者告诉被观察者要撤销观察,被观察者从容器中将观察者去除。
  观察者将自己注册到被观察者的容器中时,被观察者不应该过问观察者的具体类型,而是应该使用观察者的接口。这样的优点是:假定程序中还有别的观察者,那么只要这个观察者也是相同的接口实现即可。一个被观察者可以对应多个观察者,当被观察者发生变化的时候,他可以将消息一一通知给所有的观察者。基于接口,而不是具体的实现——这一点为程序提供了更大的灵活性。
以上就是对观察者模式最简单的介绍。
 
js实例代码:
/*---------------------------
    defined observer
----------------------------*/
function Observer()//观察者
{
   
}
//更新界面
Observer.prototype.update = function(context)//观察者方法
{
    alert("Base response " + context);;
}
 
function ConcreteObserver()//具体观察者
{
  
}
ConcreteObserver.prototype.update = function(context)//具体观察者方法
{
    alert("ConcreteObserver response " + context);
}
/*---------------------------
    defined ObserverCollection // 观察者集合
----------------------------*/
function ObserverCollection()// 观察者集合
{
    this._observers_ = new Array();  //定义数组
}
ObserverCollection.prototype.add = function(observer)  //定义数组添加方法
{
    this._observers_.push(observer);
}
ObserverCollection.prototype.remove = function(observer)  //定义数组删除方法
{
    if(_observers_ == null || _observers_=="undefined")
    {
        return null;
    }
    for(var dx=0; dx < this._observers_.length; dx++)
    {
        if(this._observers_[dx] == observer)
        {
            this.splice(this._observers_[dx],1);
        }
    }     
}
ObserverCollection.prototype.count = function()   //定义观察者集合个数
{
    return this._observers_.length;
}
ObserverCollection.prototype.getAt = function(index)   //根据索引得到具体的莫个观察者
{
    if (index > -1 && index < this._observers_.length)
    {
        return this._observers_[index];
    }
    return undefined;
}
/*---------------------------
    defined Subject
----------------------------*/
function EmergencyCase(obj)
{
    this.name = name;
    this._obs_ = new ObserverCollection();
}
//新案件
EmergencyCase.prototype.add = function(ob)  //添加观察者对象
{
    if (ob.update)
    {
        this._obs_.add(ob);
    }
}
//案件状态改变
EmergencyCase.prototype.stateChanged = function(newStatus,caseNo)
{
    var ob;
    for(var i=0; i < this._obs_.count(); i++)
    {
        ob = this._obs_.getAt(i);
        ob.update(newStatus,caseNo);   
    }
}
//分局下发案件
EmergencyCase.prototype.deliverCase = function(caseNo,acceptDepartment, deliverComment)
{
    if (this.name != newName)
    {
        this.name = newName;
        this.nameChanged();
    }
}
function test()
{
    var sub = new EmergencyCase("jjy");
    sub.add(new Observer());
    sub.add(new ConcreteObserver());
    sub.stateChanged("Send","01102331234567");
   // sub.stateChanged("Quit","01102331234567");
}
 
参考资料:
posted @ 2009-04-20 23:08  qianerHusbend  阅读(1182)  评论(0)    收藏  举报