UML _ 状态机图
概述
对现实世界中事物的观察
现实世界中的各种事物通常都有一个生命周期。在事物被创建后,经过一定阶段的变迁,它可能就结束或消亡了。
例如:生物会经历出生、成长、衰老和死亡的过程;网上购物时,会经历提交订单、待付款、待发货、待收货、待评价、交易成功等过程。
对现实世界中事物的观察结论
很多事物在其生命历程中经历了不同的状态,这些状态是根据对现实的理解并按某种条件或状况而定义的。
事物在任何时候都会处于某种状态中,所有事物都有状态;事物在各时期内所处的状态是明确的。
在现实世界存在着引起事物的状态发生变化的事件,导致事物在不同状态间按顺序转化。
事物从一个状态到另一个状态的变化,通常是即时的,不考虑转换时间。
当事件发生时,事物可能需要采取一些动作。
状态机
状态机是一个类的对象所有可能的生命历程的模型,包含了一个对象在其生命周期内所有的状态序列以及对象接收到事件后所产生的状态转换。
状态机是一个对象的局部视图,用于精确描述一个单独对象的行为。
状态机是表示有限个状态以及这些状态之间转换的模型。
【判断题】状态机描述一个对象的生命周期的动态行为,不能描述多个对象之间的行为协作。对
状态机的组成
主要由对象的各个状态和连接这些状态的转换组成。
全部的组成元素为以下5种:
-
状态:对象在其生命周期中的一种状况;
-
转换:两个状态之间的一种关系;
-
(触发)事件:引起状态变化的事情;
-
动作:状态机中可以执行的原子操作(在运行过程中不能被其他消息所中断);
-
活动:状态机中进行的非原子操作(对象处于某个状态时进行的一系列动作)。
状态机图
定义
UML 1和UML 2名字有所不同
- UML 1 状态图(Statechart Diagram)
- UML 2 状态机图(State Machine Diagram)
状态机图是描述一个特定对象在整个生命周期内,在外部事件的作用下,响应事件所经历的状态变化序列的模型图。
应用场景
常用于对系统行为中受事件驱动的方面进行建模,适合于述跨越多个用例的单个对象的行为,而不适合描述多个对象之间的行为协作。
状态机与状态机图
一个状态机图本质上就是一个状态机或状态机的特殊情况的展示。
状态机是一种行为,状态机图显示了一个状态机的所有特征。
状态机图通常完整包含初始状态、终止状态、状态和转换。
状态机图的作用
- 清晰地描述了状态之间的转换及其顺序;
- 清晰地描述了状态转换时所需的触发事件、监护条件和动作等影响转换的因素;
- 清晰的事件顺序有利于程序员在开发程序时避免出现事件错序的情况;
- 通过判定(选择)可以更好地描述工作流因为不同条件发生的分支。
状态机图的组成
-
状态
初始状态、终止状态
简单状态、组合状态、子状态机状态
历史状态 -
转换
-
分支
选择 choice
接合 junction -
同步
分岔(分叉)fork
汇合 join
状态
基本概念
状态是指在对象的生命周期中满足某些条件、执行某些活动或等待某些事件时的一个状况。
注意
-
对象在任何时候都会处于某种状态中,所有对象都有状态。
-
对象所处的状态决定了它如何响应所检测到的事件或所接收的消息。
处于相同状态的对象,对同一事件具 有同样方式的反应;处于不同状态下的对象,会通过不同的动作,对同一事件做出 不同的反应。 -
通常,事件使对象从一个状态转向另一个状态(即状态的转换)。
-
状态具有一定的时间稳定性,即在一 段有限时间内,保持对象或系统的外在状况和内在特性的相对稳定。
表示
用圆角矩形表示,由状态名和活动组成。
- 状态名一般位于圆角矩形中的第一栏。
- 活动放在第二栏,一般由入口动作、出口动作、内部活动、内部转换构成;还可以有子状态和子状态机。
注意:状态可以只包含状态名。
状态名(name)
给对象所处状态取的名字,用一个字符串表示的唯一标识符。
注意状态名字不能出现状态两字
活动
入口动作和出口动作
目的:封装状态
可以不必知道状态的内部情况而在外部使用它。
例:对密码输入(Enter Password)状态,
在进入该状态时,首先要清空密码输入框中的字符;在离开该状态前,对密码进行验证,看是否符合指定要求。
入口动作(entry action)
当进入状态时,所执行的动作;通常用来进行状态所需的内部初始化。
执行时间:
进入状态时,入口动作在进入转换上的动作之后、状态的任何内部活动之前执行。
格式: entry/进入动作名字
出口动作(exit action)
当退出状态时,所执行的动作;通常用来表示从一个状态离开时要进行的处理工作。
执行时间
退出状态时,出口动作在所有内部活动完成之后、离开转换的动作之前执行。
格式:exit/退出动作名字
内部活动
内部活动(internal action)指对象处于该状态时执行的需要一定时间且可以中断的工作。
内部活动一直持续到某个外部事件的到来才中断工作,或者活动结束、状态完成,触发转换。
格式: do/活动名
内部转换和延迟事件
内部转换(internal transition)
不导致状态改变的转换
;只有源状态,没有目标状态,不会执行entry和exit动作。
格式: event 事件名(参数)[监护条件]/动作
注意:
内部转换和自转换不同。
延迟事件(defer Event)
也称为可推迟事件,是状态中被延迟处理的事件,是一种特殊的内部转换,不会引起状态的改变;
当对象处于该状态时,事件不会丢失,但会被延迟执行;另一个状态被激活前,才对其进行处理。
语法格式: event 延迟事件名字/defer
例如:当在Email程序中编辑邮件时,如果在上传第一个附件时,用户下达上传第二个附件的指令,就会被延迟; 当第一个附件上传完成后,第二个附件就会被上传。
常用动作
常用动作建议表示方法
动作类型 | 语法 | 描述 |
---|---|---|
赋值 | Target:=expression | 对一个变量赋值 |
调用 | OpName(arg1,arg2) | 调用目标对象的一个操作,等待操作执行结束并可能获取一个返回值 |
创建 | new ClassName(arg1,arg2) | 创建一个新对象 |
销毁 | Object.destory() | 销毁一个对象 |
返回 | return value | 为调用者指定返回值 |
发送 | SignalName(arg1,arg2) | 创建一个信号实例,并将其发送到一个或一组目标对象 |
中断 | Terminate | 对象的自我销毁 |
不可中断 | [语言说明] | 用语言说明的动作,如条件和迭代 |
状态分类
初始状态(初态)
终止状态(终态)
简单状态(状态)
复合状态(组合状态)
历史状态
初始状态和终止状态
初始状态
初始状态代表状态机的起始位置。
初态是瞬时的,对象不可能保持在初态,必须有一个输出的无触发转换。从初始状态到普通状态的转换可以包含监护条件和动作,但不能包含触发事件。
注意:
- 初态是一个伪状态(是一种抽象的瞬时状态)。
- 初态只能作为转换的源,不能作为转换的目标。
- 初态在一个状态机图中只允许有一个。嵌套状态中可以使用新的初态。
终止状态
终止状态代表状态机的终止点。
对象可以保持在终态,但不可能有任何形式的输出触发转换。
注意:
- 终止状态不是伪状态!
- 终态只能作为转换的目标,不能作为转换的源。
- 终止状态在一个状态机图中可以有多个。
简单状态
状态由圆角矩形表示,其描述包括状态名、入口和出口动作、内部活动、内部转换等。
复合状态和子状态机状态
复合状态(Composite State)
是内部嵌套有子状态的状态,也称为组合状态。
可以具有初态和终态。
注意
内层和外层两个初态不能连接
,如果有内层状态,则初始状态连接到子状态的边框,不能连接到子状态的初始状态。
子状态机状态(Submachine State)
是引用了一个状态机的状态,它从概念上是将一个状态机“内嵌”到该状态;这是一种复用手段。
例子
对于运行就是子状态状态,就是引用其他的状态机状态
starUML中使用关键字include
历史状态
历史状态(History State)是一个伪状态
,记录组合状态
退出时所处的子状态,以便再次进入时从这个状态开始工作。
分类
浅历史:记忆同级别的最后子状态
深历史:记忆所有级别的最后子状态
转换
基本概念
转换用于表示一个状态机的两个状态之间的一种关系。
组成:
一个转换由源状态、触发事件、监护条件、动作和目标状态五部分
组成,这五部分不必同时存在。
对象处于源状态时,当某个特定事件发生并满足特定条件,将执行一定的动作,进入目标状态。
动作 在UML 2中名字为:效果列表
注意:
-
在这个状态变化中,称作转换被激发了。
激发之前对象所处的状态,就是源状态;激发之后对象所处的状态,就是目标状态。 -
源状态和目标状态都是相对某一个转换而言的。
表示
转换用带箭头的实线段表示,箭尾连接源状态,箭头指向目标状态。
除了源状态和目标状态,一个转换还可以包括触发事件、监护条件和动作。
语法格式:
\([转换名称:]触发事件[(参数表)] [监护条件] / [动作]\)
转换名称一般不写
触发事件/事件
简称事件(Event,也称为事件触发器)是外部作用于一个对象、能够触发对象状态改变的一种现象。
注意
-
事件可以是系统的内部事件,也可以是外部事件。
外部事件是在系统和它的参与者之间传送的事件
内部事件是在系统内部的对象之间传送的事件。 -
事件包含一个参数列表(可能为空),用于事件的产生者向其接收者传递消息。
事件分类
事件可以分成几种,主要包括:信号事件、调用事件、改变事件和时间事件等。
事件类型 | 描述 | 语法 |
---|---|---|
信号事件 | 接收对象间显式的命名的通信 | 信号名(参数) |
调用事件 | 接收一个对象显式的调用请求 | 方法名(参数) |
改变事件 | 对布尔表达式值的修改 | when(表达式) |
时间事件 | 一个绝对时间的到达,或相对时间的消耗 | after(时间段)at(时间点) |
信号事件(Signal Event)
是指一个对象对发送给它的信号的接收事件,可能会在接收对象的状态机内触发转换。
调用事件(Call Event)
是指一个对象对调用的接收,这个对象利用状态的转换而不是利用固定的处理过程实现操作。
注意
就算没有参数,也要写括号
分类
-
同步调用
如果调用者需要等待操作的完成,则是同步调用。 -
异步调用
不等待就是异步
改变事件(Change Event)
是指特定布尔表达式所表示的条件满足时,事件发生改变。
语法格式: when(表达式)
注意改变事件与监护条件的区别;
- 改变事件隐含一个对条件的连续计算,直到条件为真激发转换。
- 监护条件只在动作发生时,判断一次
时间事件(Time Event)
表示时间表达式被满足的事件,代表时间的流逝。
语法格式:
after (相对时间)或at (绝对时间)
例如:after(2 seconds), at(12:00PM)
监护条件
监护条件(Guard Condition)是一个布尔表达式,它是触发转换必须满足的条件;
注意
- 若转换没有监护条件,则默认为真。
- 监护条件的值只在事件被处理时计算一次。
例:旅游计划的状态
动作/效果列表
动作(action)是转换激活时执行的行为,也称为效果(effect) 、效果列表(effect list)。
也就是说:当转换被激活后,如果定义了相应动作,则执行该动作。
注意:
-
动作是
原子性的
,因此不可中断。 -
动作一般是一个简短的处理过程,可以是发送信号、调用操作、创建或销毁对象、读取或设置属性的值、设置返回值,甚至是一个包含多个动作的动作序列
转换分类
- 外部转换
- 内部转换
- 自转换( 自身转换)
- 自动转换(完成转换)
自转换和自动转换都是特殊的外部转换
外部转换
(就是上面学习的,最一般的转换)
对事件做出响应,引起状态变化或自身转换,同时引发一个特定动作。
语法:\(事件[(参数)] [监护条件] / 动作\)
自动转换
自动转换表示当与源状态相关的活动完成时就会自动触发。
是没有明确标明触发事件的转换,是由状态中活动的完成引起的,也称为完成转换。
特点:没有(触发)事件 但可以有监护条件,这个监护条件在状态中的内部活动完成时被赋值。
语法:[监护条件] / 动作
内部转换和自转换
内部转换
对内部事件做出响应,并执行一个特定的活动,但不引起状态变化 或 进入、退出转换。
注意:内部转换是一种活动,位于状态的第二栏。
语法: \(event 事件[(参数)][监护条件] / 动作\)
表示:状态的第二栏
自转换
转换被激活后离开当前状态,又回到当前状态,这种转换叫做自转换;也称自身转换。
注意: 自转换是源状态和目标状态为同一状态的转换,是特殊的外部转换。
表示 指向状态本身的带箭头曲线表示。
内部转换与自转换的区别:
- 内部转换不会执行entry和exit动作,不引起状态的改变。
- 自转换会引起entry和exit动作的执行,状态改变:状态A-x-状态A。
自转换一般是因为: 事件触发 但是因为监护条件 又回到本状态
分支
分支是为了说明 非并发工作流的分支与连接。
分类:选择 与 接合。
注意:
-
选择和接合都是伪状态节点。
-
选择和接合仅仅是一种表示上的方便,使用与否不影响转换的语义。
如果使用逻辑表达更清楚。
选择
选择(choice)用来表示在外部事件的作用下,根据监护条件的不同值,转向不同的目标状态。
实际就是工作流在此处按监护条件的取值发生分支,根据监护条件的真假可以触发不同的分支转换。
注意:
- 选择节点有一个输入和多个输出
- 根据监护条件的真假,触发不同的分支转换。
表示: 用空心菱形表示
接合
接合(junction),(可以省略) 用于把多条分支转换连接到一个单一的路径上,有多个输入和一个输出。
表示: 用小实心圆表示
同步
同步是为了说明并发工作流的分叉与汇合。
分类:分岔/分叉 与 汇合。
表示
同步用粗线段表示,有水平和垂直两种同步符号。
分岔(分叉,fork)
从一个单一状态进入多个状态,把一个单独工作流分成两个到多个并行进行的分支工作流;
汇合( join)
从多个状态进入一个状态,两个到多个并发工作流得到同步,即所有的工作流到达后才继续执行。
复合(组合)状态
概述
一个复合状态包括一系列子状态,也称组合状态。
子状态: 被嵌套在另外一个状态中的状态。
复合状态: 内部嵌套有子状态的状态。
分类:
复合状态可以分解为并行或互斥的子状态,所以复合状态分为
- 并发(正交)
- 顺序(非正交)
表示
有两种表达方式,根据子状态的复杂程度来选。
-
将子状态机嵌入表示状态的圆角矩形中;
-
在圆角矩形中加入分解指示符,即“子状态机状态”。
顺序复合状态
复合状态通过“或”关系分解为互相排斥的顺序子状态。
在其包含的多个直接子状态中,当复合状态被激活时,只有一个子状态会被激活。
注意:
- 顺序复合状态(非正交状态)只包含一个状态机。
- 最多可以有一个初态和一个终态。
- 当状态机通过转换进入复合状态时,一个转换可以 以复合状态为目标,也可以 以其子状态为目标。
并发复合状态
复合状态通过“与”关系分解为并发子状态。
注意:
- 并发复合状态(正交状态)包含两个或多个并发的子状态机。
- 一个区域只能有一个子状态机
- 多个区域是并行执行的
表示:
并发组合状态中有多个区域,各个区域用虚线分开,每个区域都有一个相对独立的子状态机。
子状态机通信
子状态机之间通信借助于属性来描述。
要求:完成实验1,才能进行团队项目。
实现:实验一完成lab设为true;团队项目的监护条件是lab
状态机图的应用
一个完整的系统往往包含很多的类和对象,这就可能需要创建几个状态机图来进行描述。
状态机图建模,通常应用在以下两个方面:
1. 对 对象的生命期建模
一般情况下,一个状态机依附于一个类,用来描述这个类的实例的状态及其转换,和对接收到的事件所做出的响应。(例如:订单、电梯)
2. 对 用例执行的生命期建模
状态机也可以依附于用例、操作、协作等元素上,描述其执行过程。(例如:登录、电梯运行)
状态机图的建模过程
一个完整的系统往往包含很多的类和对象,这就可能需要创建几个状态机图来进行描述。
状态机图的建模过程:
-
识别建模对象
-
识别对象的各种状态 ,并绘制状态机图
-
标识转换和事件 ,并细化状态机图
-
细化状态和转换 ,并细化状态机图
绘制状态机图的基本步骤
- 创建状态机图
- 创建初态和终态
- 创建状态
- 创建转换
- 创建事件、监护条件、动作
示例
航班机票预订系统
1. 识别对象
对于该系统,将机票看成一个整体。
2. 识别对象的各种状态
考察机票的状态:
①无预订 ②部分预订 ③预订完 ④预订关闭
可能有的外部事件:预订( )、退订( )、关闭( )、取消航班( )
3. 确定状态间的转换
4. 细化状态与转换
添加内部转换、进入和退出转换及相关活动