本站在上一篇文章中给大家介绍了状态机图的相关知识,在这一季中我将带领大家来了解一下UML中的活动图。
活动图是一种用于描述系统行为的模型视图,它可以用来描述系统的工作流程和并发行为,用于展现参与系统某一行为的类进行的各种活动的顺序关系。
活动图类似于流程图,可以描述过程逻辑、业务流程和工作流,但活动图支持并发行为。
下图是一个活动图的例子,它对教师的授课过程进行了描述。
从这个活动图中,我们可以知道一个教师授课的过程包括的主要活动有:起立、复习和提问、讲授新课、播放PPT、书写板书、注意学生行为、与学生互动、总结本次课内容及布置练习和作业等。同时,通过活动图可以看到各个活动之间的衔接关系内容。
活动图的主要元素包括动作状态、活动状态、组合活动、分叉与汇合、分支与合并、泳道、对象流等。
动作状态(Action State)是构造活动图的最小单位,它用于表示原子动作或操作的执行状态。
动作的原子性决定了动作状态不能被分解为更小的部分,且动作一旦开始就不能被中断,直到执行完毕;
动作状态的执行具有瞬时性,即执行时间极短,甚至可以忽略其执行的时间。
动作状态没有内部转换或内部活动,不能由事件触发,但可以有转入,转入可以是对象流或动作流。
动作状态包含至少一个转出。
动作状态与状态图中的状态不同,它不能有入口动作和出口动作。
在UML中,动作状态使用下面的图形来表示:
活动状态是非原子性的,可以分解成其它子活动或动作状态,也可以被中断,占有有限的时间。
活动状态可以理解为软件中的一个子过程,而动作状态则可以理解为基本的处理语句。
如果活动状态只包括一个动作,则该活动状态就是动作状态。因此,可以认为动作状态是活动状态的一种特殊情形。
在UML中,活动状态所使用的的图形与动作状态相同,只不过活动状态可以有入口动作、出口动作和状态动作等。
下面是活动状态的一个例子。
这组合活动是一种内嵌活动图的活动状态。
把不包含内嵌活动或动作的活动称为简单活动。而把内嵌了其他活动或动作的活动称为组合活动。
组合活动不具有原子性,可以被中断。
在实际中,组合活动过于复杂会增加理解上的困难,因此,可以把组合活动中的子活动单独绘制为一个图。
下面是组合活动的一个例子。
在一些系统中,可能存在着在同一时刻,有两个或两个以上的并发控制流的情况。在UML中可以使用同步条来说明这些控制流的分叉(fork)和汇合(joint)情况。
一个分叉是把一个控制流分解成两个或多个并发的控制流。
汇合表示两个或多个并发控制流在此取得同步。
在UML中,使用同步条来表示分叉和汇合。
同步条是一条水平或垂直的粗线。
下图是一个分叉和汇合的例子。
上图中,在“开始上课”活动之后,使用了分叉,该分叉有一个进入转移,有多个转出转移,“播放PPT”、“书写板书”和“观察学生反映”是在授课过程存在同时进行的情况,属于并发的活动。
这些活动结束后,有一个汇合,这个汇合有多个进入转移和一个转出转移。
分叉的转出转移数量应与汇合处的转入转移数量相同。
分支(Branch)在程序设计中是一种非常常见的结构,它根据不同的条件进入到不同的路径中执行。在活动图中也有类似的处理。
活动图中也使用一个菱形图标来表示一个判定。
一般一个判定有一个进入路径,两个或两个以上的转出路径。
每个转出路径上都有一个监护条件,当监护条件为真时,进入该路径。
转出路径上的监护条件应该是相斥的,不能重叠,且无遗漏的条件。
如“x>=1”和“x>-1”这两个条件就存在着重叠情况,若满足两个路径上的监护条件时,要进入到哪个转出路径呢?
又如“x>0”和"x<0"这两个条件就存在着遗漏条件的情况,若当“x=0”时,该怎么办呢?
这些反应到实际系统中,都可能导致系统的错误或隐含的BUG。
下图是一个分支与合并的例子。
在上面这个图书借阅的例子中,在“获取读者借阅信息”活动后有一个判定,如果读者的借阅数量“达到最大借阅数量”,则执行“停止借阅”活动,否则,图书馆工作人员可以执行“扫描待借书籍”活动,每执行一次这样的活动之后,也要进行判定,以确保读者的借阅数量未超过最大借阅数量。
借助活动图可以清楚的描述业务或处理的过程,但无法清楚的表达这些活动或动作是由谁来完成的。
泳道(Swimlane)技术可以帮助我们解决这一问题,它将活动或动作按执行的对象进行分组,每一组使用泳道来隔开。这样,即清楚的描述了活动或动作的转移情况,又表达清楚了这些活动或动作是由谁来完成的。
每个泳道都以对象的名称或活动者的名称来命名,这些名称在一个活动图中是唯一的。
活动或动作位于泳道内,不可以跨越泳道,而活动的转移可以跨越泳道。
下图是使用泳道的一个活动图。
上图描述的是一个图书馆工作人员帮助读者还书的活动图。从图中,我们可以清楚的知道,一个还书过程是由“图书馆工作人员”和“读者”这两个参与者来完成的,并且知道整个还书过程中,这两个参与者都做了哪些活动。
可以在活动图中添加对象,来表示某个活动或动作要使用或输出的对象。
把涉及到的对象放在活动图中,使用依赖关系将对象链接到对它们进行创建、撤销或修改的活动转换上。这种活动与对象的依赖关系和对象的应用被称之为对象流(Object Flow)。
对象流可用于的场景:动作状态对对象的使用以及动作状态对对象的影响。
从对象指向活动或动作的链接代表活动或动作在处理时要使用的对象。
从活动或动作指向对象的链接表示活动或动作输出的对象。
在UML中使用一个矩形框来表示一个对象。名称可以直接使用对象的名称,也可以使用“对象名:所属类名”的方式来命名。使用虚线箭头反向动作与对象之间的依赖关系。
对象中可包含对象所处的状态。
下图是一个包含对象流的活动图。
上图中的“oBook:Book”、“oBorrowRecords:BorrowRecords”和“oFineRecords:Fine”是对象,在“[]”中的内容是表示对象所处的状态。
“扫描待还书籍”将产生一个图书的对象,并修改图书状态为“在架”,“确认还书”时将修改借阅记录,更新借阅记录中的还书日期等信息,修改图书的状态为“在架”。
(1)描述一个操作执行过程中所完成的工作,说明角色、工作流、组织和对象是如何工作的。
(2)对用例的工作流进行建模。说明用例的实例是如何执行动作以及如何改变对象状态。
(3)帮助相关人员理解业务处理过程。
(4)描述复杂过程的算法。
活动图用于对系统的动态行为建模。
在建模时,通常选择对业务流程建模或对用例的交互进行建模。
对业务流程建模时,可以遵循以下步骤:
(1)选择要描述的业务过程,找出业务过程中的关键对象或参与者,将重要的对象或参与者从左到右依次排开;
(2)为反应动作状态的执行者,为这些对象或参与者添加泳道;
(3)找出业务的关键动作状态或活动节点,在对应的泳道中添加动作状态或活动;
(4)确定业务的起始点及结束状态,为活动图添加初始状态和结束状态;
(5)从起始状态开始,按照动作的发生次序,依次添加到活动图中;
(6)连接动作状态,并根据业务情况,添加分叉与汇合、分支与合并等节点;
(7)如需描述对象的情况,使用对象流来补充活动图。
(8)审查活动图中是否有遗漏或需要进一步说明的地方,是否需要使用另外一个活动图进一步描述某些活动。
对用例进行活动图建模时可以遵照以下基本步骤:
(1)选定要建模的用例,确定用例执行的基本流程;
(2)通过用例的事件流找出参与者的主动动作,把这些动作整理为活动图中的动作状态或活动状态;
(3)为参与到用例基本流程的参与者和系统添加泳道;
(4)把动作状态和活动状态添加到对应的泳道中;
(5)使用分叉与汇合、分支与合并来描述用例执行中的并发动作和特殊事件的备选动作;
(6)审查活动图是否符合实际情况,是否有遗漏,以及是否需要借助另外一个活动图来描述活动的情况。
在UML中,可以在用例视图、逻辑视图中创建活动图,也可以给一个用例、一个类、一个接口、一个类的操作等创建活动图。
在逻辑视图或用例视图或一个具体的用例、类上等右击,然后选择“New”(新建)—>“Activity Diagram”(活动图)。
如下图所示的操作。
用户可以在创建活动图的时候,直接给活动图命名,也可以通过如下方式给活动图重新命名。
(1)在重新命名的活动图上右击,然后选择“Rename”;
(2)选中要重新命名的活动图,然后再点击一下,这时可以给其输入一个新的名称。
创建完活动图后,双击打开创建的活动图,则在对象浏览器和绘图区中间部分显示创建活动图用到的基本绘图工具。
用户可以在工具箱上右击,然后选择“Customize...”来定制工具箱,如把对象、依赖箭头等添加到工具箱中来。
Rose中提供的活动图工具箱全部内容如下:
在活动图工具箱中选择“Activity”(添加活动)工具,在绘图区中点击一下,即完成图形的创建,然后可以通过下面的某一种方式对该动作状态进行相关属性的设置。
(1)双击创建的动作状态;
(2)右击创建的动作,然后选择“Open Specification...”。
上面两种操作方式都可以打开如下图所示的对话框:
在上面的对话框的“Name”(名称)中输入动作/活动状态的名称,也可以在“Documentation”中输入对该状态的描述内容。
如果创建的是动作状态,这些信息足够了。
如果创建的是活动状态,也可以在Actions选项卡中设置对应的事件动作,这里与状态图中状态的Actions设置相同,在这里不再赘述。
在“Transitions”选项卡中可以查看与该状态有关的控制流转换。
在“Swimlanes”选项卡中可以查看该状态所处的泳道。
在工具箱中选择“State Transition”(活动/动作转换)工具,然后在源状态上按下鼠标左键,在不松开鼠标的情况下移到目的状态上,并松开鼠标,这时就创建了一个状态之间的转换。
如果创建的是一个自转换,就在工具箱中选择“Transition to self”(自转换)工具,并在发生自转换的状态上点击一下,则完成了创建。
在工具箱中选择“Swimlane”(泳道)并在绘图区点击一下,即完成了泳道的创建。
在创建时,可以直接对泳道进行命名,也可以通过双击泳道名称的位置,在弹出的对话框中的“Name”处输入泳道的名称。
创建的泳道如下图所示。
每次创建泳道时,默认从左到右依次排列,如果想移动泳道的位置,可以通过下面的方式进行操作:
在要移动的泳道的头部按下鼠标左键,然后移动泳道到指定的位置松开鼠标即完成了泳道的移动。
移动过程如下图所示:
分叉与汇合,分支与合并的创建与上面的过程相似,在此不再赘述。
在创建分支时,在判定的转出箭头的线上可以通过双击为其添加转出发生的事件和参数。这与状态机图中的转移相同。
当然,在其它动作状态或活动状态中也可以创建类似的事件和参数等内容。
在工具箱中选择“Object”(对象,如没有需要使用上面所讲的定制工具箱的方法把它以及依赖添加到工具箱中),然后在绘图区,点击一下即完成了对象的创建。
创建的对象默认形状如下:
用户在创建的同时可以给对象命名,也可以使用双击对象图形或右击后选择“Open Specification...”打开如下图所示的对话框。
在“General”选项卡中可以设置对象的如下内容:
(1)Name:对象的名称;
(2)Class:对象所属的类;
(3)State:对象的状态;
(4)Stereotype:对象的构造型;
(5)Documentation:描述文档;
(6)Persistence:对象的持久性,包括持久的,静态的和临时的三种;
(7)Multiple instance:是否多个实例。
常用的就是设置名称,对象所属的类以及对象的状态。
在“Incoming Object Flows”和“Outgoing Object Flows”中可以查看流入的转移和流出的转移。
作为本文的结尾,这里将给出两个例子用于说明活动图的实际使用的情形。
第一个例子用于说明图书馆借阅系统中图书馆工作人员帮助读者借书的一个业务过程。
第二个例子说明计算读者图书超期时计算罚款额度的计算过程。
图书馆工作人员帮助读者借书时的流程如下:
(1)读者刷取一卡通;
(2)系统读取读者的信息和借阅信息;
(3)读者有超期图书时,系统提示需要归还图书并缴纳罚款后才可以借阅;
(4)读者没有超期图书,但有欠款时,系统提示不能借阅;
(5)图书馆工作人员扫描读者的每本待借书籍;
(6)系统获取图书信息并将图书信息显示到待借列表中;
(7)图书馆工作人员扫描完待借图书后,确认借阅,则完成该次借阅过程。
使用活动图描述如下:
计算读者图书超期的罚款金额步骤如下:
(1)获取读者信息;
(2)获取读者的超期图书记录;
(3)从超期图书记录中取一条记录;
(4)计算该书的超期天数;
(5)该书的罚款金额=超期天数×超期罚款金额单位数量;
(6)将该书的罚款金额累加到罚款金额变量中;
(7)对每本超期图书重复进行(4)-(6)步;
(8)输出超期罚款金额。
使用活动图描述如下:
以上内容介绍了UML中活动图的相关知识及在Rose中绘制活动图的方法,如有问题,请在文后留言。
新闻热点
疑难解答