知识卡片

事件驱动风格

普通读书笔记卡

内容

面向对象等风格靠组件显式调用彼此的过程或函数来交互,事件驱动风格提供了另一条路径——隐式调用(implicit invocation):组件不直接调用一个过程,而是发布或广播一个或多个事件,系统中其他组件通过注册与某个事件关联的过程,表示对该事件感兴趣;事件发生时,系统本身会自动调用所有注册了这个事件的过程。这种风格最核心的特点是发布者不知道哪些组件会受到事件影响,组件不能对事件的处理顺序或处理结果做任何假设——正因如此,许多事件驱动系统会保留显式调用作为组件交互的补充。优点有三:事件声明者不需要知道哪些组件会响应事件,组件间关联较弱;只要在系统事件中注册组件的过程就能把该组件集成进系统,提高软件复用能力;只要组件名和注册的过程名不变,原有组件就可以被新组件无缝替代,便于系统升级。缺点也很直接:组件放弃了对计算的控制权,触发事件后既不能保证其他组件一定响应,也不知道它们会如何处理;数据交换有时依赖共享缓冲区,性能和资源管理可能成为瓶颈;正确性验证困难,因为发布事件的过程的具体含义与事件激发的上下文相关,不像传统过程调用那样只需考虑前置/后置条件。典型案例是Field系统中的调试器断点处理:调试器停在断点上时只需发布一个事件,既不需要知道哪些工具(如编辑器、变量监视器)注册了这个事件,也不需要知道它们收到事件后会做什么;另一个典型案例是Windows的消息循环机制,靠4种消息来源(输入/控制/系统/用户消息)和消息队列实现事件的产生与处理,程序流程由事件发生的(随机、不确定的)顺序驱动,而非固定的执行顺序。

参考来源

- 位置:《软件架构理论与实践》第4章《软件架构的风格与模式》"4.3.5 事件驱动风格"节(源文件:_epub-src/OEBPS/text00034.html) - 结论依据:原文说明"这种风格的基本思想是不直接调用一个过程,而是发布或广播一个或多个事件……当这个事件发生时,系统本身会调用所有注册了这个事件的过程",并举Field系统调试器断点处理为例说明"它既不需要知道其他工具或动作是否与这个事件相关联,也不需要知道这个事件发布后它们将要做什么",直接支撑本卡片结论。 - 原始内容:这种风格的主要特点是,事件发布者不知道哪些组件会受到事件的影响。这样,组件不能对事件的处理顺序或者事件发生后的处理结果做任何假设……在这个方案中,调试器仅仅发布一个事件,但是它既不需要知道其他工具或动作是否与这个事件相关联。