[Design Pattern] The Observer Pattern

    作者:Flyingis

    在讨论设计模式时,我喜欢用英文名来称呼各种模式,觉得这样会更为准确一些。设计模式在Java开发领域已经是炙手可热的山芋,披上了这件战袍,似乎就可以在程序设计中立于不败之地,不仅可以规范自己的武功招式,还能够看清其他高手的武功套路。在接下来[Design Pattern]一系列的随笔中,我将系统的研究各种常用的设计模式,主要的参考资料是《Head First Design Patterns》,主要的思路是,介绍基本概念(虽然做Java开发的熟手已经对此熟悉的不得了),将思维转换为代码设计,谈谈在实际中开发的应用,也许还会有各种模式的弊端。

    Observer模式是常用的几种设计模式之一,其主要组成部分有:一组关注事件发生的对象,当事件发生时对象应该做的具体事情,以及决定对象参与或退出关注事件行为的控制器。注意,现在不要站在软件设计的角度上来考虑前面的这些名词,站在生活的角度上来看待会更为恰当。《Head First Design Patterns》中介绍的例子通俗易懂,老板决定哪些人成为他某个项目组的员工,去参与某个项目的开发,当然他也可以将某员工从项目组中调离出来,或是开除。在这个过程中,员工就是关注事件发生的对象,某个项目的开发即员工应该做的具体事情,老板拥有控制与调度的权利。

    Observer在程序设计中使用最为广泛是事件响应机制。列举《Ajax in Action》中的一段代码:

ExpandedBlockStart.gif ContractedBlock.gif /**/ /*  命名空间对象  */
None.gif
var  jsEvent = new  Array();
None.gif
ExpandedBlockStart.gifContractedBlock.gif
/**/ /*
InBlock.gifel:DOM元素
InBlock.gifeventType:JavaScript事件类型,如onclick、onmousemove等
ExpandedBlockEnd.gif
*/

ExpandedBlockStart.gifContractedBlock.gifjsEvent.EventRouter
= function (el,eventType) dot.gif {
InBlock.gif  
this .lsnrs = new  Array();
InBlock.gif  
this .el = el;
InBlock.gif  el.eventRouter
= this ;
InBlock.gif  el[eventType]
= jsEvent.EventRouter.callback;
ExpandedBlockEnd.gif}

None.gif
ExpandedBlockStart.gifContractedBlock.gif
/**/ /*
InBlock.gif增加一个监听器
ExpandedBlockEnd.gif
*/

ExpandedBlockStart.gifContractedBlock.gifjsEvent.EventRouter.prototype.addListener
= function (lsnr) dot.gif {
InBlock.gif  
this .lsnrs.append(lsnr, true );
ExpandedBlockEnd.gif}

None.gif
ExpandedBlockStart.gifContractedBlock.gif
/**/ /*
InBlock.gif去除一个监听器
ExpandedBlockEnd.gif
*/

ExpandedBlockStart.gifContractedBlock.gifjsEvent.EventRouter.prototype.removeListener
= function (lsnr) dot.gif {
InBlock.gif  
this .lsnrs.remove(lsnr);
ExpandedBlockEnd.gif}

None.gif
ExpandedBlockStart.gifContractedBlock.gif
/**/ /*
InBlock.gif通知所有需要响应事件的方法,当事件产生时即调用这些方法
ExpandedBlockEnd.gif
*/

ExpandedBlockStart.gifContractedBlock.gifjsEvent.EventRouter.prototype.notify
= function (e) dot.gif {
InBlock.gif  
var  lsnrs = this .lsnrs;
ExpandedSubBlockStart.gifContractedSubBlock.gif  
for ( var  i = 0 ;i < lsnrs.length;i ++ ) dot.gif {
InBlock.gif    
var  lsnr = lsnrs[i];
InBlock.gif    lsnr.call(
this ,e);
ExpandedSubBlockEnd.gif  }

ExpandedBlockEnd.gif}

None.gif
ExpandedBlockStart.gifContractedBlock.gif
/**/ /*
InBlock.gif定义事件回调函数,this指向DOM元素
ExpandedBlockEnd.gif
*/

ExpandedBlockStart.gifContractedBlock.gifjsEvent.EventRouter.callback
= function (event) dot.gif {
InBlock.gif  
var  e = event  ||  window.event;
InBlock.gif  
var  router = this .eventRouter;
InBlock.gif  router.notify(e)
ExpandedBlockEnd.gif}

    其中,关注事件发生的对象是lsnr,被保存在一系列的数组lsnrs中。事件产生时应该做的具体事情在notify方法体现。控制器则是removeListener和addListener来完成,它们决定需要哪些对象来关注事件的发生(这里说的“对象”仍然是广义的,非面向对象中的“对象”)。这样就完成了一个简单的JavaScript事件响应的设计,遵循的是Observer设计模式。

    Java API内建了一些接口、类来帮助实现Observer模式,具体可以参考java.util包中的Observer接口和Observable类。

    Observer模式在软件设计中使用的非常广泛,在事件响应、对象监控、动态响应等领域具有重要的实际应用价值,除此之外,它还可以有效帮助软件设计向Loosely Coupled Design方向发展,降低模块之间的耦合,顺应软件设计发展的潮流。但是,对于一个简单的,对扩展性没有太多要求的应用而言,刻意在应用中引入Observer模式,只会增加代码量,对软件的快速开发和效率提升没有任何好处,还不如将代码写的简单易懂更好。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值