当转换被引起时,它对应的动作被执行。动作是原子性的,一般是一个简短的计算处理过程,通常是一个赋值操作或算术计算。另外还有一些动作,包括给另一个对象发送消息、调用一个操作、设置返回值、创建和销毁对象,没有被定义的控制动作用外部语言来进行详细说明。动作也可以是一个动作序列,即一系列简单的动作。动作或动作序列的执行不会被同时发生的其他动作影响或终止。按照 UML 中的概念,动作的执行时间非常短,与外界事件所经历的时间相比是可以忽略的,因此,在动作的执行过程中不能再插入其他事件。然而,实际上任何动作的执行都要耗费一定时间,新到来的事件必须被安置在一个队列中。
整个系统可以在同一时间执行多个动作。我们说动作是原子性的,并不是说整个系统是原子性的。系统能够处理硬件的中断和多个动作的时间共享。动作在它的控制线程中是原子性的。一旦开始执行,它必须执行到底并且不能与同时处于活动状态的动作发生交互作用。但动作不能用于表达处理过程很长的事物。与系统处理外部事件所需要的反应时间相比,动作的执行过程应该很简洁,否则系统不能够做到实时响应。
一个动作可以使用触发器事件的参数和对象的属性值作为表达式的一部分。
表 6–3 动作的种类
· 6. 状态改变当动作执行完毕后,转换的目标状态被激活,这时会触发出口动作或入口动作的执行。
· 7. 嵌套状态状态可以被嵌套在其他的组成状态之内(看下一段)。从一个外部状态出发的转换可以应用于这个状态所有的内部嵌套状态。任何一个内部嵌套状态被激活时,转换都有可能发生。组成状态可用于表达例外和异常,因为组成状态上的转换适用于所有它所嵌套的状态,不需要每个嵌套状态显式地单独处理异常。
· 8. 入口和出口动作一个跨越多个嵌套层次的转换可能会离开或进入某个状态。只要转换进入或离开某个状态,则该状态可能包含要被执行的动作。进入一个状态可能会执行一个依附于该状态的入口动作。如果转换离开初始状态,那么在转换的动作和新状态的入口动作被执行前,执行该状态的出口动作。
入口动作通常用来进行状态所需要的内部初始化。因为不能回避一个入口动作,任何状态内的动作在执行前都可以假定状态的初始化工作已经完成,不需要考虑如何进入这个状态。同样,无论何时从一个状态离开都要执行一个出口动作来进行后处理工作。当出现代表错误情况的高层转换使嵌套状态异常终止时,出口动作特别有用。出口动作可以处理这种情况以使对象的状态保持前后一致。入口动作和出口动作原则上依附于进来的和出去的转换,但是将它们声明为特殊的动作可以使状态的定义不依赖状态的转换,因此起到封装的作用。
· 9. 内部转换内部转换有一个源状态但是没有目标状态。内部转换的激发规则和改变状态的转换的激发规则相同。由于内部转换没有目标状态,因此转换激发的结果不改变本状态。如果一个内部转换带有动作,它也要被执行,但是没有状态改变发生,因此也不需要执行入口和出口动作。内部转换用于对不改变状态的插入动作建立模型(如,记录发生的事件数目或建立帮助信息屏)。
尽管入口动作和出口动作的执行是由进入或离开某状态的外部转换所引起的,除了使用保留字 entry 和 exit 代替触发事件名称之外,入口和出口动作使用与内部转换相同的表示法。
一个自身转移会激发状态上的入口动作和出口动作的执行(从概念上来讲,自身转换从一个状态出发后又会到自身状态),因此,自身转换不等价于内部转换。 图 6 – 4 说明了入口动作、出口动作和内部转换。

图 6–4 内部转、入口动作和出口动作

