Event-Listerner事件监听模式


事件监听模式其实就是一种观察者模式,只是角度有点不同,在Java的JavaBean机制以及GUI中都使用了事件监听模式。在如今AJAX RIA客户端中,事件监听模式也成为一个主要的界面模式。

事件监听模式分同步和异步两种实现方式,JavaBean机制和GUI基本都是同步机制,事件监听异步模型,需要引入Event Queue。

事件监听同步模式分两个部分:Event Source和Event Listener:
Event Source:被监听者的事件集合,可能是方法,提供事件的注册加入和移除功能。类似被观察者的集合。
Event Listener:事件的监听者,当事件被触发,所有监听这个事件的监听者将被通知,然后执行自己的Action响应动作。

事件监听异步模式在Source和Listener之间引入event queue,
event queue是一个基于事件的publish-subscribe. 它一种松耦合方式提供不同模块和角色之间异步通讯。它比同步更加松耦合,这样,我们就把Source-Listener改成了publish-queue-subscribe方式。

事件监听模式使用在客户端RIA比较多,因为这里是用户输入的源头,是事件发生的源头。而且在目前WOA趋势下,事件监听模式不能只单独局限于RIA客户端这个范围,还需要把事件通过http形式传递到服务器端,也就是跨客户端和服务器的,事件必须和服务器的PUSH异步结合在一起。这是一种先进的架构设计。

基于Javascript的ZK 5 RIA已经实现了这种先进的事件监听模式,见:
http://docs.zkoss.org/wiki/ZK_5:_Chat_with_Event_QueueEvent_queues_and_server_push

如果将这种异步的事件模式和服务器的OSGI结合,那么在服务器端更新一个Jar模块,可以主动通知到客户端浏览器,
这对服务器端模块管理很有好处。
http://bundle-exception.blogspot.com/2009/07/zk-on-osgi-dynamic-asynchronous.html

记得在Header First设计模式中,MVC被看成一种复合设计模式,是策略模式和观察者模式的有机组合(很多其他文献中把MVC层看成一种架构风格),其谈到MVC设计CS的时候可以严禁的实现策略模式和观察者模式,但是MVC面对BS时候尤其是现在主流框架在jsp/servlet上没法支持观察者模式,因为你不可能把jsp注册为model的观察者,所以jsp/servlet一直从根据上不支持push,以至于主流push技术都需要客户端首先发起请求“我需要接下来的一段时间里你每10面更新一次新闻”,之后才可以开启push。
所以我在考虑是不是可以基于freemaker封装一个模板,然后摒弃jsp,而实现自己可注册监听的服务页技术呢?

严格来说:MVC模式是一种同步机制,MVC的Controller是Mediator模式,而Mediator模式的特点和缺点就是封装通讯,而Observer模式则是分离通讯。

实践证明:象Observer这种分离通讯的做法是符合可伸缩性要求的,而Mediator模式这种封装通讯是不可伸缩的。

所以,可以说MVC模式是不可伸缩的,所以,才有REST替代一说,也可以在MVC中引入事件模式。ZK5的设计就是这种基于MVC模式基础上的事件异步架构。

所以,现在只是使用一个MVC的Web框架已经远远不满足伸缩性要求。

说得不客气的话:现在所有的基于MVC框架,如Struts 2或Webwork JSF Wicket,如果不在其上引入异步事件框架,都是不合格的,都是落后的技术。

> 现在所有的基于MVC框架,如Struts 2或Webwork JSF Wicket,如果不在其上引入异步事件框架,都是不合格的,都是落后的技术。

我觉得这些MVC框架不支持异步是因为其基于jsp/servlet封装起来的,servlet2.x 全都不支持异步,底层都不支持,指望上层架构如何能实现?所以要么等servlet3.0规范为大多数应用服务器实现之时,要么干脆摒弃jsp/servlet和主流servlet容器,用mina封装通讯,第三方包解析http,freemaker定制页面模板,实现真正的异步。

>干脆摒弃jsp/servlet和主流servlet容器,用mina封装通讯
这才是最灵活 最伸缩的好办法,也是我目前推崇的。

OSGI的白板模式Whiteboard Pattern比原始监听模式的要更进一步,将OSGI的事件机制引入,相当于producer + OSGI + Consumer。白板模式具体见:http://www.osgi.org/wiki/uploads/Links/whiteboard.pdf

文中案例代码是利用OSGI本身的ServiceTracker服务跟踪监听类作为Listener的触发机制,这样,基于OSGI开发事件模式,就不用把Listener注册到Source,从而发生紧耦合,只要双方直接注册到OSGI中就可以了。

这就是利用service registry来实现双方的解耦,也就是利用OSGI框架内部bundle(inter-bundle)依赖来实现event source和event listener的松耦合,可节省维持event source和event listener之间事件关系代码。

TSS上一篇文章利用OSGI的版本模式实现了IRC机器人聊天的功能,并在Consumer方实现一个onMessage方法,这个方法非常类似JMS中Consumer的onMessage,
文章代码如下:
The Whiteboard Pattern for OSGi
http://www.theserverside.com/news/thread.tss?thread_id=49380

个人认为:OSGI的这种producer + OSGI + Consumer和zk5的publish-queue-subscribe异步有些类似之处,或者可以说,可以将OSGI白板模式作为异步事件模式使用。因为事件生产方产生事件后就自行结束,属于fire and forget方式。



[该贴被admin于2009-08-16 09:15修改过]