`
zerozone
  • 浏览: 205753 次
  • 来自: 北京
社区版块
存档分类
最新评论

基于Prototype实现对象级别Observer模式

阅读更多

Prototype框架提供了基于JavaScript语言的面向对象风格的AJAX库,使编写动态WEB程序成为可能。基于PrototypeScriptaculous的流行就是一个很好的证明。<o:p></o:p>

<o:p></o:p>Prototype封装了FormElementEvent,并为Form提供了Observer模式以便于进行事件管理和减少依赖。<o:p></o:p>

问题:<o:p></o:p>

<o:p></o:p>Prototype设计了两种Observer,一种基于Timeout,一种基于事件。但无法支持普通对象级别的Observer。例如在调用A对象的X 方法之后触发B对象的Y方法。本文将尝试一种在对象级别实现Observer的方式。<o:p></o:p>

分析:<o:p></o:p>

<o:p></o:p>Observer模式实现在“被观察者”的行为发生变化时,向多个对象(观察者)发生消息(并由该对象完成Update操作)。面向对象语言借助Interface实现Observer模式。如Java中的java.util.Observable相当于Subject(被观察者),而java.util.Observer接口的实现者(观察者)完成Update操作。

上述方式对于降低类之间依赖不错。但是我们必须从特定的类继承或实现特定的接口。Observer消息触发方式导致问题也需要考虑。详见:http://www.microsoft.com/china/MSDN/library/architecture/patterns/esp/DesObserver.mspx?mfr=true<o:p></o:p>

当然,我们可以在JavaScript中按照上述结构实现Observer会导致更多问题,例如如何实现接口编程?即使这个问题很容易解决,无论从理解和使用上这种模式都不太方便、不够直接。<o:p></o:p>

设计:<o:p></o:p>

再次聚焦Observer模式并观察它的核心,会发现如何实现消息触发是关键。一旦ConcreteSubject对象拥有ConcreteObserver的引用,在消息触发时就可以直接调用后者的Update方法。<o:p></o:p>

<o:p></o:p>
代码执行顺序:
<o:p></o:p>

concreteSubject的对象内部:<o:p></o:p>

if(this.stateChanged())<o:p></o:p>

     concreteObservers.update(this,args);<o:p></o:p>

再看我的问题:在调用A对象X方法之后调用B对象的Y方法。<o:p></o:p>

A对象内部:<o:p></o:p>

this.X();<o:p></o:p>

B.Y();<o:p></o:p>

<o:p></o:p>动态语言特性支持在Runtime时刻改变对象(数据和行为)。考虑引入对象Observer及方法register。用户期望A对象的X方法调用后触发B对象Y方法时,将A对象、X方法名称和期望的动作(B.Y)传入register方法,然后在该方法中改写X的行为。<o:p></o:p>

       A. _$_X = A.X;<o:p></o:p>

       A.X = {this._$_X(); B.Y();}<o:p></o:p>

<o:p></o:p>
同时增加
unregister方法设法恢复A对象的行为(X方法)。<o:p></o:p>

<o:p> </o:p>
代码:
<o:p>  </o:p> 

 

js 代码
 
  1. var StringBuffer = Class.create();  
  2. StringBuffer.prototype = {    
  3.     emptyString:"",  
  4.     initialize:function(){  
  5.         this.data=[];  
  6.     },  
  7.     clear:function(){  
  8.         this.data.length=0;  
  9.     },  
  10.     append:function(){        
  11.         for(var i=0,len=arguments.length;i
  12.             this.data[this.data.length]=arguments[i];  
  13.         }  
  14.         return this;  
  15.     },  
  16.     toString:function(){  
  17.         return this.data.join(this.emptyString);  
  18.     }     
  19. };  
  20.   
  21. var Observer = Class.create();  
  22. Observer.prototype = {    
  23.     initialize:function(){  
  24.           
  25.     },  
  26.     /** 
  27.      * register the action to the object's method 
  28.      * @param {Object} object 
  29.      * @param {String} method 
  30.      * @param {String} action 
  31.      */  
  32.     register:function(object,method,action){  
  33.         if(!object || !method || !action || method == typeof String || action == typeof String)return;  
  34.   
  35.         //checks whether the method is existed.   
  36.         var f = object[method];  
  37.         if(!f)return;  
  38.           
  39.         //copy, rename the method and replace it as a new method.  
  40.         var _$_f = "_$_"+method;          
  41.         if(!object[_$_f]){  
  42.             object[_$_f] = f;  
  43.             object[method]= this.createFunction(method,action);           
  44.         }  
  45.     },  
  46.     /** 
  47.      * unregister the action from the object's method 
  48.      * @param {Object} object 
  49.      * @param {Object} method 
  50.      */  
  51.     unregister:function(object,method){  
  52.         if(!object||!method)return;  
  53.         var _$_f = "_$_"+method;      
  54.         if(object[_$_f]){  
  55.             object[method] = null;  
  56.             object[method] = object[_$_f];  
  57.             object[_$_f] = null;  
  58.         }     
  59.     },  
  60.     /** 
  61.      * create a new function that invokes both the method and the action  
  62.      * @param {String} method 
  63.      * @param {String} action 
  64.      */  
  65.     createFunction:function(method,action){  
  66.         var sb = new StringBuffer();  
  67.         sb.append("this[\"_$_",method,"\"]();\r",action);         
  68.         return new Function(sb.toString());  
  69.     }     
  70. }  
分享到:
评论
6 楼 sp42 2007-06-06  
Oh~God Bless you,guys,
--至少在AJAX时代里,还允许我们名正言顺地玩一下js.再看看一个command模式的小小实现,嘻嘻~
先定义一个Command对象,代码如下:
function Command(obj) {
    var commandObj = obj;       // save the reference of working object
    var oldProp = new Object(); // save old properties 
    
    // set new properties and save old properties
    this.Do = function() {
        for (var o in this) {
            oldProp[o] = commandObj[o];
            commandObj[o] = this[o];
        }
    }
    
    // restore old properties
    this.Undo = function() { 
        for (var o in oldProp) {
            commandObj[o] = oldProp[o];
        }

        delete oldProp;
        oldProp = new Object();
    }
}

如果要调用,这样写就可以了:
// "mc" is an object that has _alpha and _x attributes

var com = new Command(mc);
com._alpha = 20;
com._x = 200;
com.Do();
// do something...
// remember to save this Command somewhere...

// now, undo it! 
com.Undo();
5 楼 jianfeng008cn 2007-06-06  
想对自己说好好学学设计模式吧,那是思想而不是单纯的code,无论你是js java lisp 还是smalltalk。
4 楼 radar 2007-06-06  
sp42 写道
radar 写道
http://yuiblog.com/blog/2007/01/17/event-plan/
http://developer.yahoo.com/yui/docs/CustomEvent.js.html

yui早就以这来设计组件了,看看yui,yui-ext充满了event.
yui-ext对其进行一定的扩展.

另外dojo.connect更是用的有点走火魔了。

yui-ext的observable简直就是我的最爱,没办法--太sexy了
--我甚至把它应用在服务端的JS(asp)
s
其实没必要把obserbable看的那么神秘高深的.
都是被java害苦的,其实对于很多动态语言来说,这不算什么.

aop其实也是这样,在java,c#中,aop好象是救世主一样,在很多动态语言中,什么aop什么的,语言级别就支持了.

还有设计模式,在动态语言眼中, 小kiss啦.

尤其是在服务器端,选择太多了.


感叹一声,和我一样,生长在java,c#阳光下的coder
3 楼 sp42 2007-06-06  
radar 写道
http://yuiblog.com/blog/2007/01/17/event-plan/
http://developer.yahoo.com/yui/docs/CustomEvent.js.html

yui早就以这来设计组件了,看看yui,yui-ext充满了event.
yui-ext对其进行一定的扩展.

另外dojo.connect更是用的有点走火魔了。

yui-ext的observable简直就是我的最爱,没办法--太sexy了
--我甚至把它应用在服务端的JS(asp)
2 楼 radar 2007-06-06  
http://yuiblog.com/blog/2007/01/17/event-plan/
http://developer.yahoo.com/yui/docs/CustomEvent.js.html

yui早就以这来设计组件了,看看yui,yui-ext充满了event.
yui-ext对其进行一定的扩展.

另外dojo.connect更是用的有点走火魔了。
1 楼 sp42 2007-06-06  
Observer 100%是整个ajax中最为sex的一个

相关推荐

    Observer模式

    Observer模式是实现分布式事件处理、状态机以及组件通信的有效工具。 在Java中,Observer模式主要通过java.util.Observable和java.util.Observer接口来实现。Observable类代表被观察的对象,Observer接口定义了观察...

    observer模式实现示例

    Observer模式是一种设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。在C++编程中,Observer模式通常通过函数指针或者接口来实现,这两种方法...

    OBserver模式设计实现

    观察者模式(Observer Pattern)是一种行为设计模式,它允许你定义一个订阅机制,可以在对象状态改变时通知多个“观察”该对象的其他对象。在Java和C++等面向对象编程语言中,这种模式广泛用于事件处理和实时系统,...

    Observer设计模式实例

    Observer设计模式,也被称为“发布-订阅”(Publish-Subscribe)模式或“依赖倒置”模式,是软件设计中的一种行为模式。...在Java、C#、Python等面向对象语言中,都有内置的Observer支持,使得实现这一模式更加便捷。

    Observer模式的传统实现和AOP实现

    对Observer模式的实现,引入后可直接使用。 包括传统实现和遵循AOP思想的实现

    Observer模式代码实现

    本例展示了如何使用观察者模式来实现对象之间的松耦合。通过定义抽象的 `Subject` 和 `Observer` 类,可以很容易地扩展新的被观察者和观察者类型。此外,通过将观察者添加到被观察者列表中,并在被观察者状态变化时...

    重温Observer模式--热水器·改

    Observer模式是一种设计模式,主要目的是实现对象之间的松耦合,使得当一个对象的状态发生改变时,依赖于这个对象状态的其他对象能够得到通知并自动更新。在这个“重温Observer模式--热水器·改”的讨论中,作者将...

    C#面向对象设计模式纵横谈(19):(行为型模式) Observer 观察者模式 (Level 300)

    **C#面向对象设计模式纵横谈(19)**:**观察者模式**(Observer Pattern)是行为型模式的一种,它在软件工程中扮演着至关重要的角色。观察者模式是一种设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态...

    Observer与Command模式在VTK类库设计中的应用研究

    在VTK中,Observer模式的实现基于以下概念: - **目标对象**(Subject):负责存储观察者的列表,并在状态发生变化时通知它们。 - **观察者对象**(Observer):接收目标对象的通知,并根据这些通知采取相应的行动...

    C++ Observer模式

    Observer模式,也称为“订阅”或“发布-订阅”模式,是软件设计中的一种行为模式,主要用于处理对象间的一对多依赖关系。当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这个模式在C++中...

    设计模式之Observer

    Observer模式,又称为“观察者模式”或“发布-订阅模式”,是一种行为设计模式,用于在对象之间建立一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。Observer模式...

    Observer 模式

    Observer模式是一种行为设计模式,它允许你定义一个订阅机制,可以在对象状态改变时通知多个“观察者”对象,使得它们能够自动更新自己。这个模式在软件工程中扮演着重要的角色,尤其是在事件驱动或数据绑定的系统中...

    Observer模式的应用

    请选用适当的设计模式,编写一个股票行情分析软件,随着时间的推移和股票价格的变动,实现各种指标的动态更新(要求至少实现一个股票的分时图和K线图:为降低编程工作量,K线图可以用开盘价、收盘价、最高价、最低价...

    设计模式之观察者模式(Observer Pattern)

    在"ObserverPattern(简单实现)1.rar"中,我们可以看到一个简单的观察者模式实现。主题类(Subject)通常包含一个添加、删除和通知观察者的接口。当主题状态改变时,它会调用`notifyObservers()`方法,将变化通知给...

    Observer设计模式

    总之,Observer设计模式是软件设计中一种常用且实用的模式,它能够有效地实现对象间的通信和状态同步,有助于构建可维护、可扩展的系统。在Java编程中,我们可以利用内置的Observable和Observer类,或者选择更适合...

    23种面向对象设计模式

    3. **行为型模式**(Behavioral Patterns):关注对象之间的责任分配和通信,包括策略模式(Strategy)、模板方法模式(Template Method)、迭代器模式(Iterator)、观察者模式(Observer)、访问者模式(Visitor)...

    设计模式C++学习之观察者模式(Observer)

    观察者模式(Observer)是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。这种模式在C++中广泛应用,特别是在需要...

    观察者模式,Observer

    观察者模式(Observer Pattern)是设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。这种模式常用于实现事件驱动的系统或者...

    observer观察者模式

    观察者模式(Observer Pattern)是一种行为设计模式,它允许你定义一个订阅机制,可以在对象状态改变时通知多个“观察”该对象的其他对象。在软件工程中,这常用于实现事件驱动编程,使得系统能够及时响应变化。 在...

    C#面向对象设计模式纵横谈(视频与源码)

    C#面向对象设计模式纵横谈(6):Prototype 原型模式(创建型模式) C#面向对象设计模式纵横谈(7):Adapter 适配器模式(结构型模式) C#面向对象设计模式纵横谈(8):Bridge 桥接模式(结构型模式) C#面向对象设计...

Global site tag (gtag.js) - Google Analytics