软件体系结构风格---基于事件的隐式调用

来源:互联网 发布:js decode 编辑:程序博客网 时间:2024/06/09 19:57
  • 构件不直接调用一个过程,而是触发或广播一个或多个事件。系统中的其它构件中的过程在一个或多个事件中注册,当一个事件被触发,系统自动调用在这个事件中注册的所有过程,这样,一个事件的触发就导致了另一模块中的过程的调用。
  • 构件是一些模块,这些模块既可以是一些过程,又可以是一些事件的集合。过程可以用通用的方式调用,也可以在系统事件中注册一些过程,当发生这些事件时,过程被调用。
1、事件驱动风格
事件驱动系统的基本观点是一个系统对外部的表现可以从它对事件的处理表征出来。如下图所示:

[软件体系结构]基于事件的隐式调用风格 - 蔷薇阁 - 落落工作室
 2、事件驱动模式的特点
  • 系统是由若干子系统或元素所组成的一个整体;
  • 系统有一定的目标,各子系统在某一种消息机制的控制下,为了这个目标而协调行动;
  • 在某一种消息机制的控制下,系统作为一个整体与环境相适应和协调;
  • 在一个系统的若干子系统中,必定有一个子系统起着主导作用,而其他子系统则处于从属地位;
  • 任一系统和系统内的任一元素,都有1个事件收集机制和1个事件处理机制,通过这种机制与周围环境发生作用和联系。
事件驱动的软件系统示意图
[软件体系结构]基于事件的隐式调用风格 - 蔷薇阁 - 落落工作室
 3、事件驱动模式系统设计原则
  • 从系统论的角度来看待描述的对象,合理分解子系统,保证各个子系统的独立性和社会性
  •  无论系统多么复杂,子系统性质的差异多么大,任何子系统都可以按照有无子系统这一性质分为2类:管理系统和执行系统。
  •  为了达到系统的目标,系统内的各个子系统通过传递消息和执行消息来协同操作。
  • 在一个完整系统中,必须有这样一个子系统,它没有上级,必须收集系统外的事件及下级发出的事件。
  • 管理类型的子系统一般不执行具体操作,其主要功能是按照自己的职能指挥下级完成任务,功能性操作一般由执行类型的子系统完成。
  • 一般情况下,除最高级管理子系统外,子系统一般是“有问才答”,即使在必要的情况下需要积极寻找事件时,也必须征得上级系统得许可,保证了系统的控制流不会分散。
4、事件驱动模式的基本结构
  • 事件驱动系统具有某种意义上的递归性,形成了“部分-整体”的层次结构,可以用属性结构加以表示。
  • 一个简单的表示方法是为执行系统定义一些类,另外定义一些类作为这些执行系统的容器类,也就是管理系统。
[软件体系结构]基于事件的隐式调用风格 - 蔷薇阁 - 落落工作室
 5、事件驱动模式的优点
  • 适合于描述系统族:在属于同一族的任何系统中,系统的高级管理子系统的描述是完全类似的,便于重用。
  • 容易实现并发处理和多任务操作:由于最高管理子系统牢牢的掌握着控制权,又因为各同级子系统一般不直接发生关系。
  • 具有良好的可扩展性:设计者只需为某个对象注册一个事件处理接口就可以将该对象引入整个系统,同时并不影响其它的系统对象。
  • 类结构简明:定义了包含执行子系统和管理子系统的类层次结构。
  • 简化客户代码:使整个系统的设计更具有一般化。
6、事件驱动模式的缺点
  • 构件削弱了自身对系统计算的控制能力。
  • 数据共享能力降低。
  • 系统中各个对象的逻辑关系变得更加复杂。
7、事件驱动模式与面向对象模式
  • 基于面向对象模式的系统由多个封装起来的对象构成,对象之间通过消息传递实现通信,而事件驱动正是对消息传递机制的一种实现。
  • 基于事件驱动模式的系统往往都是面向对象的。

8、实例:JavaBean系统
  • 事件从事件源到监听者的传递是通过对目标监听者对象的Java方法调用进行的。
  • 对每个明确的事件的发生,都相应地定义一个明确的Java方法。
  • 这些方法都集中定义在事件监听者(EventListener)接口中,这个接口要继承java.util.EventListener
事件状态对象
  • 与事件发生有关的状态信息一般都封装在一个事件状态对象中,这种对象是java.util.EventObject的子类。
  • 按设计习惯,这种事件状态对象类的名应以Event结尾。
事件监听者接口(EventListener Interface)与事件监听者
  • 由于Java事件模型是基于方法调用,因而需要一个定义并组织事件操纵方法的方式。JavaBean中,事件操纵方法都被定义在继承了java.util.EventListener类的EventListener接口中,按规定,EventListener接口的命名要以Listener结尾。
  • 任何一个类如果想操纵在EventListener接口中定义的方法都必须以实现这个接口方式进行。这个类也就是事件监听者。
事件监听者的注册与注销
  • 为了各种可能的事件监听者把自己注册入合适的事件源中,建立源与事件监听者间的事件流,事件源必须为事件监听者提供注册和注销的方法。在前面的bound属性介绍中已看到了这种使用过程,在实际中,事件监听者的注册和注销要使用标准的设计格式:
  • public void add< ListenerType>< ListenerType> listener
  • public void remove< ListenerType>(< ListenerType> listener);
适配类
  • 适配类是JavaBean事件模型中极其重要的一部分。在一些应用场合,事件从源到监听者之间的传递要通过适配类来“转发”。
  • 适配类成为了事件监听者,事件源实际是把适配类作为监听者注册入监听者队列中,而真正的事件响应者并未在监听者队列中,事件响应者应做的动作由适配类决定。
9、隐式调用示意图
[软件体系结构]基于事件的隐式调用风格 - 蔷薇阁 - 落落工作室
10、基于事件的隐式调用风格特点
事件的触发者并不知道哪些构件会被这些事件影响:不能假定构件的处理顺序,甚至不知道哪些过程会被调用;为此,许多隐式调用的系统也包含显式调用作为构件交互的补充形式。
11、支持隐式调用的系统
  • 在编程环境中用于集成各种工具。
  • 在数据库管理系统中确保数据的一致性约束。
  • 在用户界面系统中管理数据。
  • 在编辑器中支持语法检查等。

12、集成开发环境
  • 在某集成开发环境中,编辑器和变量监视器可以登记相应Debugger的断点事件。
  • Debugger在断点处停下时,它声明该事件,由系统自动调用处理程序,如编辑程序可以卷屏到断点,变量监视器刷新变量数值。
  • Debugger本身只声明事件,并不关心哪些过程会启动,也不关心这些过程做什么处理。
13、隐式调用系统的主要优点
  • 为软件重用提供了强大的支持。当需要将一个构件加入现存系统中时,只需将它注册到系统的事件中。
  • 为改进系统带来了方便。当用一个构件代替另一个构件时,不会影响到其它构件的接口。
14、隐式调用系统的主要缺点
  • 构件放弃了对系统计算的控制一个构件触发一个事件时,不能确定其它构件是否会响应它。即使它知道事件注册了哪些构件的构成,它也不能保证这些过程被调用的顺序。
  • 数据交换的问题有时数据可被一个事件传递,但另一些情况下,基于事件的系统必须依靠一个共享的仓库进行交互。这也使全局性能和资源管理便成了问题。
  • 正确性的推理存在问题这是由于过程的语义必须依赖于被触发事件的上下文约束。
0 0
原创粉丝点击