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


事件是什么?
那么,到底事件是什么?在软件系统中要如何表达一个事件?一个事件应 该包括两个东西:识别事件的名称(event identity),和事件的相关的数据(event data)。例如,一个键盘按键被按下的事件可能叫KeyPressedEvent, 事件数据则为该按键的代码。
先前提到发布事件是用调用方法的方式(回调),不过有一个问题,就是publisher无法事先知道subscriber 的类型。在Java的编码模式当中,回调可以使用接口模式,也就是publisher必需事先定义好一个在发布事件中使用的接口,subscriber实现该接口中的方 法,publisher则通过调用接口中的方法来完成发布事件的工作。如下图:

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

所以C#期望使用函数指针类型来作为事件的识别名称,然后用函数的参数来传递事件数据。我们先用一段C 代码来描绘这幅图画 :
// 定义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;
// 定义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;
748



被折叠的 条评论
为什么被折叠?



