8.3.4 顺序图
(1)顺序图概述。顺序图是用来显示参与者如何以一系列顺序的步骤与系统的对象交互的模型。顺序图可以用来展示对象之间是如何进行交互的。顺序图将显示的重点放在消息序列上,即强调消息是如何在对象之间被发送和接收的。
类图描述了系统中的类以及类间的关系,但是没有详细说明对象的行为,也没有详细说明对象之间如何交互。
顺序图又称序列图,描述对象之间的动态交互关系,着重表现对象间消息传递的时间顺序,是一种详细表示对象之间以及对象与参与者之间行为关系的图,由一组协作的对象(或参与者)以及它们之间可发送的消息组成,强调消息之间的顺序。
(2)顺序图的组成。顺序图由四部分组成:参与者、生命线、激活期与消息。下面分别介绍。
1)参与者(actor)或者对象(object)具有以下四个特点。
①参与者和对象按照从左到右的顺序排列。
②一般最多两个参与者,他们分列两端。启动这个用例的参与者往往排在最左边,接收消息的参与者则排在最右端。
③对象从左到右按照重要性排列或按照消息先后顺序排列。
④将对象置于顺序图的顶部意味着在交互开始的时候对象就已经存在了,如果对象的位置不在顶部,那么表示对象是在交互的过程中被创建的。
对象的命名方式有三种,包括对象名和类名、类名(匿名对象)、对象名(不关心类)。顺序表示如图8.30所示。

图8.30 对象的命名
2)生命线(lifeline)具有以下几个特点。
①每个对象都有自己的生命线,用来表示在该用例中一个对象在一段时间内的存在。
②垂直的虚线。
③如果对象生命期结束,则用注销符号表示。生命线表示如图8.31所示。

图8.31 生命线
3)激活期(activation)/控制焦点(focus of control)。
①对象在一段时间内获得了焦点,也称激活期;
②对象执行某个动作的时期;
③空心矩形条;
④激活期的长短意味着对象执行某个动作的时间有多长,可以通过约束来限制执行时间的长短。激活期如图8.32所示。

图8.32 激活期
4)消息(message)。面向对象方法中,消息是对象间交互信息的主要方式。结构化程序设计中,模块间传递信息的方式主要是过程(或函数)调用。对象A向对象B发送消息,可以简单地理解为对象A调用对象B的一个操作(operation)。
消息具有如下三个特点。
①顺序图中,尽力保持消息的顺序是从左到右排列的。
②一个顺序图的消息流开始于左上方,消息2的位置比消息1低,这意味着消息2的顺序比消息1要迟。
③顺序图中消息编号可显示,也可不显示。
主要的消息介绍如下。
①调用消息。消息的发送者把控制传递给消息的接收者,等待接收者返回或放弃控制,可以表示同步。调用消息必有一个与之配对的返回消息,但是可以不用画出。实心箭头符号。
如类Driver向类Car传递了open()消息,如图8.33所示。

图8.33 调用消息
②异步消息。消息的发送者把控制传递给消息的接收者,然后继续自己的工作,不等待接收者返回或放弃控制。如图8.34所示。

图8.34 异步消息
③返回消息(Return)。表示消息的返回。消息上方放置返回值,也可以不画出,直接隐含。虚线箭头表示,虚线表示返回消息。如图8.35所示。

图8.35 返回消息

图8.36 自调用消息
④阻止消息。消息的发送者传递消息给接收者,如果接收者无法立即接收,则发送者放弃该消息。
⑤超时消息。消息的发送者发出消息给接收者并按指定时间等待,若接收者无法在指定时间内接收,则发送者放弃该消息。
⑥自调用。某对象自己调用自己的操作,用嵌套的矩形条表示。如图8.36所示,对象Source调用自己的操作。
5)建立顺序图的步骤。(https://www.daowen.com)
①确定交互过程的上下文;
②识别参与交互过程的对象;
③为每个对象设置生命线;
④从引发这个交互过程的初始消息开始,在生命线之间自顶向下依次画出随后的各个消息;
⑤如果需要嵌套或表示消息发生的时间点,使用控制焦点;
⑥如果需要说明时间约束,则在消息旁边加上约束说明;
⑦如果需要,可以为每个消息设置前置条件和后置条件。
下面以个人图书馆里系统为例介绍如何建立顺序图。
例8.5 需求描述:李小平是一个爱书之人,家里各类书籍已过千册,而平时又时常有朋友外借,因此需要一个个人图书管理系统。该系统应该能够将书籍的基本信息按计算机类、非计算机类分别建档,实现按书名、作者、类别、出版社等关键字的组合查询功能。在使用该系统录入新书籍时系统会自动按规则生成书号,可以修改信息,但一经创建就不允许删除。该系统还应该能够对书籍的外借情况进行记录,可对外借情况列表打印。另外,还希望能够对书籍的购买金额、册数按特定时间周期进行统计。
第一步:寻找分析类。
在分析阶段,常在用例中寻找三种分析类(边界类、控制类和实体类)。通过分析用例描述中的事件流,寻找分析类。
在分析时,还必须综合考虑基本事件流和扩展事件流两个方面。下面以“新增书籍”为例进行分析。其事件流如下所示。
1)基本事件流
①图书管理员向系统发出“新增书籍信息”请求。
②系统要求图书管理员选择要新增的书籍是计算机类还是非计算机类。
③图书管理员做出选择后,显示相应界面,让图书管理员输入信息,并自动根据书号规则生成书号。
④图书管理员输入书籍的相关信息,包括:书名、作者、出版社、ISBN号、开本、页数、定价、是否有CD-ROM。
⑤系统确定输入的信息中书名没有重复。
⑥系统将所输入的信息存储建档。
2)扩展事件流
①如果输入的书名有重名现象,则显示出重名的书籍,并要求图书管理员选择修改书名或取消输入。
②图书管理员选择取消输入,则结束用例,不做存储建档工作。
③图书管理员选择修改书名后,转到基本事件流中的5。
第二步:寻找边界对象。
对这个用例而言,参与者“图书管理员”,要寻找边界对象只需以“图书管理员”这个参与者为线索,从用例描述中去寻找分析类:
图书管理员向系统发出“新增书籍信息”请求。图书管理员在什么地方向系统发出“新增书籍信息”的请求呢?通常会设计一个主窗口,并在上面摆放一些按钮来实现,因此在此句描述中,可以发现两个边界类:主窗口、“新增书籍信息”按钮。
系统要求图书管理员选择要新增的书籍是计算机类还是非计算机类——从此句中可以发现一个新的边界类,书籍类别列表框。
图书管理员做出选择后,显示相应界面,让图书管理员输入信息,并自动根据书号规则生成书号——此句中可以发现最为关键的一个边界类。“新书信息录入”窗口以及辅助的“提交”按钮。
而且,还可以发现新增书籍信息按钮是组成主窗口的一部分。书籍类别列表框、提交按钮则是组成新书信息录入窗口的一部分。根据以上信息,可以先将参与者和边界对象绘制出来,其结果如图8.37所示。

图8.37 边界类对象分析
第三步:寻找控制对象和实体对象。
实体对象通常来源于领域中的类图,也就是描述业务领域的名词或名词短语,通过阅读整个事件流的详细描述,实体对象有书籍、计算机书籍、非计算机书籍以及书籍列表四个。
在这个例子中,根据扩展事件流的描述,可以在图8.37上增加相应的控制对象,得到更进一步的分析图,如下图8.38所示。

图8.38 控制对象分析
另外,还有几个关键的事件没有体现到图中,一个是基本事件流中的步骤2、3要求根据用户选择的类别自动获得书号;另一个是当书名重复性检查没有通过时(有重名),应返回要求其重输。

图8.39 最终分析图
构建顺序图的步骤如下。
首先,按照从左到右的顺序,依此将参与者、边界对象和实体对象放在最顶部,边界类放在左边,实体类放在右边。需要注意的是,在分析模型中可以先不考虑控制类的引用(当然有必要时也可以引入)。完善顺序图如图8.40所示。

图8.40 顺序图
例8.6 浏览顺序图的方法是,从上到下(按时间顺序)查看对象间交换的信息。图8.41是顺序图的一个例子。注意,从Printer Server到Printer的消息带有条件,表示当打印机空闲时发送Print消息到Printer,否则无法将store消息给Queue。

图8.41 顺序图
一个对象可以通过发送消息来创建或删除另一个对象,当一个对象被删除(或自我删除)时,用一个大“X”来标记。