工具软件   办公软件   操作系统   网络安全   设计在线   程序开发   教程宝典   软件下载   软件论坛
您的位置:软件 > 开发者网络 > 微软开发专栏 > 技术专题 > 正文
探讨与比较Java和.NET的事件处理框架
[文章信息]
作者:
时间:2004-11-25
出处:程序员杂志
责任编辑:方舟
[文章导读]
事件驱动模型是软件系统平台中的一个重要区域
advertisement
热点推荐
· Java加密和数字签名编程快速入门
· 在VB6中用命令行为模式控制GUI动作
· Excel图表向导详解
· 浅析各种计算机病毒应对方法
· 2月16日软件精选 春节文章精彩回顾
[正文]

1 2 3  下一页

  事件驱动模型

  事件驱动模型是软件系统平台中的一个重要区域,现代软件系统大量地使用事件驱动的处理方法,尤其在用户界面方面。虽然如此,过去在软件开发语言中一直没有融入事件处理的因子,直到.NET的出现,才将事件处理的工作负荷一部分的分派给编译器,从而稍微减轻开发者的负担。

  下图显示事件模型的组成份子:


  Subscriber需事先和publisher预订要接受其发布的某事件(下图a1),publisher在某事件发生以后,必需先生成该事件的相关数据对象(下图a2.1),然后通过方法调用来通知subscriber(下图a2.2),也就是用回调(callback)的方式来通知subscriber。当然在预订的时候,并不一定要由subscriber自身来预订,也可以由另一个对象来帮忙预订。其动态图形示意如下:


  本文并不探讨异步的信息传送,也就是在整个事件的处理过程当中,publisher和subscriber 对象皆需要同时存在。如果对于离线(offline)的方式来处理事件有兴趣的话,请参阅Java的JMS(Java Message Service)和.NET的LCE(Loosely Coupled Events)。

  事件是什么?

  那么,到底事件是什么?在软件系统中要如何表达一个事件?一个事件应该包括两个东西:识别事件的名称(event identity),和事件的相关的数据(event data)。例如,一个键盘按键被按下的事件可能叫KeyPressedEvent,事件数据则为该按键的代码。

  先前提到发布事件是用调用方法的方式(回调),不过有一个问题,就是publisher无法事先知道subscriber的类型。在Java的编码模式当中,回调可以使用接口模式,也就是publisher必需事先定义好一个在发布事件中使用的接口,subscriber实现该接口中的方法,publisher则通过调用接口中的方法来完成发布事件的工作。如下图:


  这样,在Java的编码模式中,一个事件的识别名称就是接口名称和其中的方法名称,而事件数据则自然是接口方法的参数了。Java对于这个接口的命名风格为XXXListener,顾名思义就是某事件的倾听者。例如:

public interface KeyListener extends EventListener {
 public void keyTyped(KeyEvent e);
 public void keyPressed(KeyEvent e);
 public void keyReleased(KeyEvent e);
}

  由于一个接口中可以包含多个方法,所以Java在设计事件的时候,是将一组相关联的事件放在一起,这样设计的优点是可以很好的将事件做分类,并且在publisher中如果要处理的事件较多的话,可以使用比较少的成员变量来记录subscribers。缺点是如果subscriber只对事件接口中的部分事件有兴趣,也必需要全盘实现该接口(所以在AWT里有java.awt.event.XXXAdapter抽象辅助类)。另一个缺点则是必需要为每一类事件定义一个接口类型,即使可能大部分的事件只有极少的方法。

  微软在为C#语言命名的时候,就刻意隐喻C#是从C/C++为基础发展而得的面向对象程序语言,始祖绝不是Java,所以肯定要保留一些C/C++的语言机制。在C/C++里面对回调的设计方式就是用函数指针,想当然C#也希望直接使用类似函数调用的方式来做为事件发布的方法。如下图:


  所以C#期望使用函数指针类型来作为事件的识别名称,然后用函数的参数来传递事件数据。我们先用一段C++代码来描绘这幅图画:

Event type definition:
// 定义KeyPressedCallback 为一个函数指针的类型,
// 该函数接受一个整数型参数,无返回值
typedef void (*KeyPressedCallback)(int keyCode);

Publisher:
class Publisher
{
 public KeyPressedCallback KeyPressedSink = null;
 ...
 void FireEvent(int KeyCode)
 {
  if (KeyPressedSink != null)
  (*KeyPressedSink)(keyCode);//callback
 }
}

Subscriber:
void KeyPressedHandler(int keyCode)
{
 ...
}
...
Publisher publisher = new Publisher();
//register
publisher.KeyPressedSink = &KeyPressedHandler;

  一个当代的纯面向对象程序语言,是肯定希望要把造成程序复杂和不易维护的指针给去除的。所以在C#语言机制当中,势必要创造新的元素来取代,于是delegate(委托)出现了。如下:

Event type definition:

// 定义KeyPressedDelegate 为一个类似函数指针的类型,
// 该函数接受一个整数型参数,无返回值
delegate void KeyPressedDelegate(int keyCode);

Publisher:
class Publisher
{
 public KeyPressedDelegate KeyPressed = null;
 ...
 void FireEvent(int KeyCode)
 {
  if (KeyPressed != null)
   KeyPressed(keyCode);
 }
}

Subscriber:
void KeyPressedHandler(int keyCode)
{
 ...
}
...
Publisher publisher = new Publisher();
//register
publisher.KeyPressed = KeyPressedHandler;

  一开始,你可以把KeyPressedDelegate当成是与函数指针相类似的东西,通过它你可以引用一个实例方法或静态方法,就好像引用一个对象一样。然后可以通过这个delegate直接调用其引用的方法。但是下面你会看到delegate更扩大了其引用能力。


1 2 3  下一页

天极社区邀请您:写博客日记  上传相片   论坛聊天  订阅电子杂志  推荐网摘   免费图铃工具
笔名:   请您注意:

 遵守国家有关法律、法规,尊重网上道德,承担一切因您的行为而直接或间接引起的法律责任。

 天极网拥有管理笔名和留言的一切权利。
评论:
 
发表评论推荐给朋友我想参加相关培训打印我对此感兴趣订阅电子杂志
相关内容焦点新闻
  • .NET框架和VS.NET中的SOAP
  • 五种常见的ASP.NET安全缺陷
  • ADO.NET2.0的十大新特性
  • 使用ADO.NET的最佳实践
  • .NET Web应用框架构建模式
  • 中兴携手阿尔卡特 全球逐鹿CDMA
  • 用友总裁王文京:誓将ERP变成“大众消费”
  • 香港消费者委员会:数码相机最贵未必最好
  • 外电称中兴正评估西门子手机业务 或能并购
  • 国信办督战八大行业灾难备份 将出台国家标准
  • 中国IT企业走进欧盟 搭第六框架计划直通车
  • 美邦银行用户注意 警惕新型“钓鱼”邮件
  • 微软三年时间磨出新IE 具有更强大安全性能
  • Advertisement

    天极无线


    奇妙科幻|美好风光|清风车影|漫画卡通|星座生肖|明星写真|动物世界
    老鼠爱大米
    挥着翅膀的女孩
    女人味
    栀子花开
    白月光
    刚刚好
    江南
    快乐崇拜
    亲爱的你怎么不在我身边
    小薇
    2002年的第一场雪
    有多少爱可以重来
    我的地盘
    七里香
    情人
     
    老鼠爱大米 老板电话
    冲动的惩罚 七里香
    我不是黄蓉 女生撒娇
    盛夏的果实 坚持到底
    孤单北半球 眉飞色舞
    挪威的森林 可爱女人
    最浪漫的事 老板电话

    CSEEK搜索