UML系列文章(21)高级行为---事件和信号

内容概览:

  • 信号事件、调用事件、时间事件和变化事件
  • 对信号族建模
  • 对异常建模
  • 处理发生在主动对象或被动对象中的事件

在现实世界中,事情在发生。不仅事情在发生,许多事情可以都在同一时间发生,而且发生在最意想不到的时间。“发生的事情”称为事件,每个事件表示一个在时间和空间上占据一定位置的有意义的发生的规约。

在状态机语境中,使用事件对能够触发状态转移的激励建模。事件包括信号、调用、时间推移或状态改变。

事件可以是同步的,也可以是异步的,因此对事件的建模涉及对进程和线程的建模。

1. 入门

完全静态地系统是极端无趣的,因为没有事情发生。所有真实系统自身都含有某些动态特性,并且这些动态特性是由内部或外部发生的事情所触发的。在一个ATM机上,动作是由一个用户按下按钮来启动一个事务而引发的。在一个自主机器人中,动作是由机器人碰上一个物体而引发的。在一个网络路由器中,动作是由检测到消息缓冲区溢出而引发的。在一个化工厂中,动作是由化学反应所需要的时间段用满而引发的。

在UML中,每件发生的事情都被建模为一个事件。事件是对在时间和空间上占据一定位置的有意义的发生的规约。信号、时间推移和状态改变是异步事件,表示能在任何时间发生的事件。调用一般是同步事件,表示对一个操作的引用。

UML提供了对事件的图形化表示,如图所示。

UML系列文章(21)高级行为---事件和信号_第1张图片

 这种表示法允许可视化事件的声明(如信号Offhook)以及用来触发一个状态转移的事件的使用(如信号OffHook,它导致了从Active到Idle的状态转移及对动作dropConnection的执行)。

2.术语和概念

    事件(event)是对一个在时间和空间上占有一定位置的有意义的发生的规约。在状态机的语境中,一个事件是一次激励的发生,激励能够触发状态转移。信号(signal)是一种事件,表示在实例间进行通信的异步消息的规约。

2.1 事件的种类

    事件可以是内部的事件或外部的事件。外部的事件是在系统和它的参与者之间传送的事件。例如一个按钮的按下和一个来自碰撞传感器的中断都是外部事件。内部事件是在系统内部对象之间传送的事件。溢出异常是一个内部事件的例子。

    可以用UML对4种事件进行建模:信号、调用、时间推移和状态的一次改变。

2.2 信号

    消息是一个具名对象,它由一个对象异步地发送,然后由另一对象接受。信号是消息的类目,它是消息的类型。

    信号和简单类有许多共同之处。例如,信号有实例,尽管一般不需要对其实例进行显式的建模。信号还可以包含在泛化关系中,以便对事件的层次结构建模,有些信号是一般的(如NetworkFailure),有些信号是特殊的(如对NetworkFailure的一个特化WarehouseServerFailure)。像类一样,信号也可以有属性和操作。在一个对象发送它之前或者在另一个对象接受后,信号只是一个普通的数据对象。

    信号可以由状态机中转移动作来发送。也可以把信号建模为交互中的两个角色间的消息。方法的执行也可以发送信号。事实上,当为一个类或一个接口建模时,说明该元素行为的一个重要部分就是说明它的操作所能发送的信号。

    在UML中,可以将信号建模为衍型化的类。可以用一个衍型为send的依赖来表示一个操作发送了一个特定的信号。

UML系列文章(21)高级行为---事件和信号_第2张图片

2.3 调用事件

    就像一个信号事件代表一个信号的发生一样,一个调用事件表示对象接受到一个操作调用请求。调用事件可能触发状态机中一个状态转移,或者调用目标对象的一个方法。这种选择由类定义中的操作定义来说明。

    信号是一个异步事件,而调用事件一般是同步的。也就是说,当一个对象调用另一个具有状态机的对象的一个操作时,控制就从发送者传送到接受者,该事件触发转移,完成操作后,接受者转移到一个新的状态,控制返回给发送者。如果调用者无需等待回应,那么可以把这个调用指定为异步调用。

    如下图所示,对调用事件的建模和对信号建模没有区别。两种情况下都把事件连同其参数表示成状态转移的触发器。

 UML系列文章(21)高级行为---事件和信号_第3张图片

2.4 时间事件和变化事件

    时间事件表示一段时间推移的事件。如图所示,在UML中,用关键字after,后面跟着计算一段时间的表达式来对一个时间事件建模。表达式可以是简单的(如after 2 seconds),也可以是复杂的(after 1ms since exiting Idle)。除非显式说明, 否则这样一个表达式的开始时间是进入当前状态的时间。使用关键字at来指出在某个绝对时间点上发生的时间事件。例如,时间事件at(1 Jan 2005, 1200 UT)指出该事件发生在格林尼治时间2005年1月1日的中午。

    变化事件是表示状态的一个变化或某些条件得到满足的事件。如下图所示,在UML中,用关键词when后面跟随布尔表达式来对一个变化事件建模。可以用这样的表达式连续的进行测试(when altitude   < 1000 )。

UML系列文章(21)高级行为---事件和信号_第4张图片

    一旦某个条件的值从假变化为真,就会引发变化事件。当条件的值由真变为假时,不会引发变化事件。当事件一直为真时,不会重复地引发变化事件。 

2.5 发送和接收事件

    信号事件和调用事件至少涉及两个对象:一个是发送信号或调用操作的对象,另一个是事件指向的对象。因为信号是异步的,而且异步调用本身也是信号,所以事件的语义与主动对象和被动对象的语义是相互影响的。

    任何类的任何实例都可以向一个接受对象发送信号或者调用其操作。区分同步调用与异步调用。

在UML中,将一个对象可能接收的调用事件建模为这个对象的类的操作。在UML中,可以通过在类的附加栏中对信号命名来为对象可能接受的具名信号进行建模,如图所示,

UML系列文章(21)高级行为---事件和信号_第5张图片

 

3.常用建模技术

3.1 对信号族建模

UML系列文章(21)高级行为---事件和信号_第6张图片

 

3.2 对异常建模

UML系列文章(21)高级行为---事件和信号_第7张图片

上图是对异常的一个层次结构建模,这些异常是由容器类(如模板类Set)的标准库产生的。这个层次结构以抽象信号Error为根,它包括3种特殊错误:Duplicate、OverFlow和Underflow。如图所示,操作add可能引发信号Duplicate和OverFlow,操作remove仅引发信号Underflow。换一种做法,可以通过在每个操作的规约中命名异常,将这些依赖放置在后台中。不论哪种方法,通过了解每个操作可能发送的所有信号,就可以创建正确的使用类Set的客户端。 

4.提示和技巧

 对事件建模时,应遵循如下策略:

  • 建立信号的层次结构,以发掘相关信号的公共特性;
  • 确保每个可能接收事件的元素背后都有一个适当的状态机;
  • 确保不仅对那些可能接收事件的元素建模,而且还对那些可能发送事件的元素建模。

在用UML绘制事件时,要遵循如下的策略:

  • 要显式地对事件的层次结构建模,但要在每个发送或接收这个事件的类的基架中对它们的使用建模。

你可能感兴趣的:(UML,uml)