





















以上定义中有几个关键词:
系统的功能由不同的用例来定义,每个用例都代表了一个特定的事件流。用例说明将定义执行用例时在系统中发生的事件。

例如,在自动柜员机中,客户可以从帐户中提取现金、将现金转入帐户或核对帐户余额。这些功能对应于可以用用例来代表的事件流。
每个用例本身就有一个要执行的任务。所收集到的用例组成了所有可能的系统使用方法。只需注意一下用例任务的名称,就可以对该用例任务有一个大致的了解。
以下问题可以帮助您确定用例:
有些用例不代表系统的主要功能,因而通常会被忽略。这些用例可能属于以下类型:
如果已经开发了业务用例模型和业务对象模型,另请参见指南:从业务模型到系统。
在精化的早期迭代中,只对少数几个用例(在构架方面有重要意义的用例)进行比简要说明更为详细的说明。在深入到细节之前,通常应该先编写用例的提纲(按照分步格式)。此分步提纲应该是您定义用例事件流结构的首次尝试(请参见下文的事件流 - 结构)。始终要从基本的用例流开始。一旦对基本流提纲形成了一致意见,就可以添加与基本流相关的备选流内容。
当精化阶段即将结束时,应完成您计划要详细说明的所有用例。
模型中通常会有一些简单的用例,它们不需要详细的事件流说明,对它们使用分步提纲就可以了。要作出这一决定,依据的标准是:您没有发现作为读者的用户对该用例的含义存在异议,而且设计人员和测试人员对于按分步格式提供的详细程度感到满意。这种简单用例的示例之一是描述简单的输入或从系统中检索某些数据的用例。
通常很难判断一组系统交互或对话是否属于一个或几个用例。请考虑回收机的使用情况。客户将贮藏物品(如罐子、瓶子和箱子)插入回收机。当插入所有的贮藏物品后,她按下某个按钮,打印了一份收据。这样,她就可以用这一收据换取现金。
是否插入贮藏物品属于一个用例,而索取收据属于另一个用例?或者,以上过程只是一个用例?此过程有两个动作,缺少了任何一个,另一个动作都对客户没有任何意义。所以,应该将所有插入和获取收据当作一个完整对话,这样才对客户有意义。因而,从插入第一个贮藏物品到按下按钮获得收据的完整对话过程是一个完整的用例,也就是一个用例。
此外,最好将这两个动作连在一起,这样就可以同时对它们进行复审、修改、测试、为它们编写手册,并且在一般情况下将它们当作一个单元来管理。在大型系统中,明显需要这样处理。
用例可以说明当主角通过与系统交互来执行该用例时在系统中发生的事件。至于系统如何在内部利用协作对象来执行任务,用例并不加以定义。这将由用例实现来说明。
示例:
以打电话为示例,用例会说明以下内容:当呼叫方拿起听筒时,系统将发出一个信号,然后,系统会接收数字输入、查找接收方、使接收方的电话振铃、接通电话、传送语音等等。
在执行系统中,用例实例并不对应于实施模型中的任何特定对象(例如,代码中类的实例)。它所对应的是特定的事件流,该事件流由主角调用并且作为一组对象中的一个事件序列来执行。也就是说,用例实例对应于被实施对象的通信实例。我们将其称为用例的实现。通常,相同的对象会参与多个用例的实现。例如,银行业务系统中的“存款”用例和“取款”用例可能在它们的实现中同时使用某个特定的帐户对象。这并不表示这两个用例可以相互通信,它们只是在它们的用例实现中使用了相同的对象。
您可以认为一个事件流是由几个分支流构成的,这几个分支流组合到一起就形成了总的事件流。您还可以在其他用例的事件流中复用某个分支流的说明。一个用例事件流说明中的分支流可能是其他用例事件流说明中所共有的分支流。在进行设计时,应该让相同的对象来执行全部相关用例所共有的行为;也就是说,无论正在执行哪个用例,只应该有一组对象执行来这一行为。
示例:
在自动取款机系统中,“取款”用例和“核对余额”用例的事件流中的初始分支流是相同的。这两个用例的事件流都从检查卡标识和客户的个人访问代码开始。
一个用例实例几乎可以遵循无限多的路径,但这些路径仍然可以计数。路径代表了用例事件流说明中的用例实例可以选择的各种方案。路径的选择取决于事件。事件类型包括:
示例:
在回收机系统的“回收贮藏物品”用例中,客户始终有两种选择:继续插入另一个贮藏物品或获得回收物品的收据。
示例:
在自动柜员机系统的“取款”用例中,如果客户要求提取的金额大于他的帐户金额,事件流就会有所不同。因而,用例实例将遵循不同的路径。
在系统允许的情况下,几个用例的实例和同一个用例的几个实例可以并行工作。在用例建模的过程中,您可以假定用例的实例可以毫无冲突地同时处于活动状态。由于用例建模不说明工作原理,所以应该用设计模型来解决这一问题。此时可以这样来看待这种情况,即假定一次只有一个用例实例处于活动状态,而且该实例的执行是一个不可分的活动。在用例建模中,“解释机”被认为是无限快的,所以用例实例的串行化不成问题。
每个用例都应有一个名称,以表明它与主角进行交互的结果。名称应该是几个便于理解的单词。用例名称不应重复。
示例:
回收机示例中的“回收贮藏物品”用例可以具有以下的不同名称:
用例的简要说明应反映用例的角色和目的。在撰写说明时,应参考用例中所涉及的主角、词汇表,并根据需要定义新概念。
以下是回收机系统中“回收贮藏物品”用例和“添加新的瓶类型”用例的简要说明示例:
回收贮藏物品:用户使用本机器来自动统计所有回收物品(瓶子、罐子以及箱子),并得到一张收据。收据将在收银机处兑现。
添加新的瓶类型:在“学习模式”中启动机器,然后与返回回收物品时一样插入 5 个样本,从而将瓶子的新类型添加到机器中。这样,回收机就能够测量这些瓶子,并知道如何识别它们。管理人员指定新的瓶类型的返款额。
用例事件流包含用例建模工作所得到的最重要的信息。应该清楚地说明用例的事件流,让外行也能很容易地理解它。请记住,事件流应该说明系统做什么,而不是说明为了执行所需的行为而对系统进行的设计。
以下提供了有关事件流内容的指南:
如果您已经在其他用例中使用了某些特定术语,则务必要在此用例中使用完全相同的术语,并确保它们表达相同的含义。为了管理常用术语,应该将它们放入一个词汇表。
事件流的两个主要部分是基本事件流和备选事件流。基本事件流应包括在执行用例时“通常”会发生的事件。备选事件流包括与正常行为相关的可选或异常特征的行为,同时也包括正常行为的各种变形。您可以将备选事件流看作是基本事件流的“绕行道”,有些备选事件流将返回到基本事件流,而有些将结束此用例的执行。

事件流的典型结构。直线箭头代表基本事件流,而曲线则代表与正常行为相关的备选事件流。有些备选路径返回到基本事件流,而其他备选路径则结束此用例。
应该将基本事件流和备选事件流进一步构建为步骤或分支流。为进行构建时,您的主要目标应该是文本的可读性(另请参见下面的事件流 - 风格一节)。这里的经验法则是,分支流应该是用例中的一个行为段,该行为段必须具有明确目的并且“不可分”(也就是说,要么执行所述的全部动作,要么不一个也不执行)。您可能会需要使用几个级别的分支流,但应尽量避免这样,因为多个级别的分支流会使文本更为复杂、更难于理解。可以用活动图来说明事件流的结构(参见指南:用例中的活动图)。
这种书面文本分为连续的小节,这本身就向读者提示:分支流之间存在一定顺序。为了避免误解,始终应该指出分支流的顺序是否是固定的。这种考虑事项通常与以下内容相关:
为了阐明备选事件流在结构中的合适位置,需要为基本事件流的每条“绕行道”说明以下内容:
示例:
在回收机系统的“回收贮藏物品”用例中有一个备选分支流。
2.1. 瓶子阻塞
在 1.5 节“插入贮藏物品”中,如果一个瓶子被卡在入口处,入口周围的传感器和测量门将检测到这个问题。传送带停止传送,机器发出警报,让操作人员来解决问题。回收机将一直等待,直到操作人员指示问题已得到解决。然后,回收机从基本事件流的 1.9 节中继续工作。
在上例中,备选事件流插入了基本事件流中的一个特定位置。有些备选事件流也可以在多个位置插入,一些备选事件流甚至可以在基本事件流中的任意位置插入。
示例:
在回收机系统的“回收贮藏物品”用例中有一个备选分支流。
2.2. 前面板被取走
如果有人将回收机的前面板取走,将使罐子压缩功能不可用。没有前面板就无法启动罐子压缩操作。取走前面板的同时将激活向操作人员发出的警报。当重新安装好前面板时,回收机又将从它在基本事件流中停止的位置恢复操作。
如果备选事件流非常简单,您可能想就在基本事件流部分对其进行说明(使用某种不正式的“if-then-else"结构)。但应该避免这样。太多的备选事件流将使正常行为难于识别。而且,如果在基本事件流部分包括备选路径,将使文本更加“类似于伪代码”,从而会降低文本的可读性。
通常,如果抽取事件流的各个部分并且分别对这些部分进行说明,就可以增加基本事件流的可读性,并改进用例和用例模型的结构。您可以将抽取的部分建模为:
可以按照多种风格来说明用例。作为示例,我们将以三种不同的风格来说明“管理订单”用例的基本事件流,它们的主要区别在于正式程度不同。第一种风格(如下面的示例 1 所示)易于理解、条理清晰,所以是推荐使用的风格。文本分为带有编号和名称的各个小节。这些编号便于对小节进行引用。小节名称使读者只需浏览文本的标题就可迅速地获得对从事件流的总体了解。
在下面的示例 2 中,事件流的说明没有阐明事件发生的顺序。如果以这种风格撰写,您和其他人都可能会错过一些与系统相关的重要信息。
下面的示例 3 显示了另外一种风格。如果您觉得很难清楚地表示事件的序列,就可以采用这种风格。这种伪代码风格更为准确,但非技术人员在阅读和理解这种文本时会有困难,尤其是在需要快速领会事件流时。
当主角操作员通知系统创建一个评测订单时,用例开始。然后,系统将检索所有的网络元素主角、它们的测评对象以及特定操作员可以使用的相应测评功能。可用的网络元素是那些正在运行的网络元素和操作员有权访问的网络元素。测评功能的可用性依赖于为某一特定类型的测评对象所设置的评测功能。
1.2. 配置测评订单
系统让操作员主角选择要评测的网络元素,然后将显示所选网络元素可以使用的测评对象。系统让操作员从这些评测对象中进行选择,然后选择需要为每个评测对象设置的评测功能。
系统让操作员输入对评测订单的文本注释。
操作员通知系统完成评测订单。系统将作出以下响应:为该评测订单生成一个唯一的名称,并设置评测开始时间、评测重复频率和评测持续时间的默认值。对于每个操作员,这些默认值都是唯一的。然后,系统让操作员编辑这些默认值。
1.3. 初始化订单
操作员通知系统初始化评测订单。系统将记录创建操作员的身份、创建日期以及测评订单的“预定”状态。
1.4. 用例结束
系统向该操作员确认已对测评订单进行了初始化,其他主角在此时可以看到该测评订单。
用例说明:在这种风格中,文本易于阅读,事件流易于理解。在您的说明中应尽量采用这种风格。
系统将给该订单分配一个唯一的名称,并指定评测持续时间和评测开始时间和评测重复频率的默认值。订货人将能够编辑这些默认值。
订货人必须进一步指定适用的评测功能、网络元素和评测对象。订货人还可以在订单上添加个人注释。
定义了必要的信息之后,将创建一个新的订单并使用已定义的属性、创建者姓名和创建日期来将这一新订单初始化。该订单的状态将被设置为“预定”。(可能的状态值包括:预定、执行、完成、取消和错误。)
然后,用户界面将得到已创建新订单的通知,同时会接收到对该新订单的引用,该引用可用来显示新订单。
用例说明:这种风格具有可读性,但事件流都不清晰。
'管理订单' (用户身份)
REPEAT
<='显示管理订单菜单'
IF (=> '创建订单' (评测功能,
网络元素,评测对象)) THEN
系统查找唯一的名称、评测开始时间
和持续时间的默认值。
<= '显示订单' (默认属性)
REPEAT
=> '编辑订单' (要更改的属性,属性的新值)
<= '屏幕刷新' (新属性)
UNTIL (定义了所有的属性)
REPEAT
IF (=> '编辑订单' (要更改的属性,属性的新值))
THEN <= '屏幕刷新' (新属性)
ELSIF (=> '保存订单' (订单标识,属性)) THEN
在系统中创建订单,并使用已定义的属性、
创建者的姓名、创建日期和“预定”状态
将订单初始化。
<= '创建的新订单' (订单)
ENDIF
UNTIL (=> '退出')
ENDIF
UNTIL '退出管理订单'
用例说明:编写员在上例中选择了一种使用伪代码的正式风格。这种风格会使读者难于快速领会流程步骤,但在不容易准确获取事件流的情况下,这种风格相当有用。
“管理订单”用例事件流的完整说明(包括其备选流)可能如下所示:
1. 基本事件流
1.1. 用例开始
当主角操作员通知系统创建一个评测订单时,用例开始。然后,系统将检索所有的网络元素主角、它们的测评对象以及特定操作员可以使用的相应测评功能。可用的网络元素是那些正在运行的网络元素和操作员有权访问的网络元素。测评功能的可用性依赖于为某一特定类型的测评对象所设置的评测功能。
1.2. 配置测评订单
系统让操作员主角选择要评测的网络元素,然后将显示所选网络元素可以使用的测评对象。系统让操作员从这些测评对象中进行选择,然后选择需要为每个测评对象设置的测评功能。
系统让操作员输入对评测订单的文本注释。
操作员通知系统完成评测订单。系统将作出以下响应:为该评测订单生成一个唯一的名称,并设置评测开始时间、评测重复频率和评测持续时间的默认值。对于每个操作员,这些默认值都是唯一的。然后,系统让操作员编辑这些默认值。
1.3. 初始化订单
操作员通知系统初始化评测订单。系统将记录创建操作员的身份、创建日期以及测评订单的“预定”状态。
1.4. 用例结束
系统向该操作员确认已对测评订单进行了初始化,其他主角在此时可以看到该测评订单。
2. 备选事件流
2.1. 没有可用的网络元素
在“1.1. 用例开始”中,如果发现目前没有该操作员可以评测的网络元素,系统将通知该操作员。该用例随即结束。
2.2. 没有可用的评测功能
在“1.2 配置评测订单”中,如果所选的网络元素没有可用的评测功能,系统将通知该操作员并让他选择其他网络元素。
2.3. 撤消评测订单
系统将允许操作员在用例执行过程中的任意时刻撤消所有动作。然后,系统将返回到该用例在开始之前所处的状态,并结束该用例。
在用例的特殊需求中,应说明事件流没有包括的所有用例需求。有些非功能性需求将会影响设计模型。另请参见指南:用例模型中关于非功能性需求的讨论。您可以将这些需求分为不同的类别,例如可用性、可靠性、性能和可置换性,但是这些需求通常数量很少,所以这样的分类不具有太大的价值。
在回收机系统中,“返回贮藏物品”用例的特殊需求可以包括:
该机器识别贮藏物品的可靠性必须高于 95%。
利用前置条件和后置条件的概念来阐明事件流如何开始和结束是一种非常有用的方法。然而,只有当用例的读者认为该方法可以增加价值时才应将其采用。

前置条件是开始用例前所必需的系统及其环境的状态。后置条件是用例结束后系统可能具备的状态。
请考虑以下方面:
示例:
自动柜员机中“提取现金”用例的前置条件为:客户拥有一张个人专用卡,这张卡正好可以塞进读卡器,并且该卡已经分到一个 PIN 号,还向银行业务系统进行了登记。
自动柜员机中“提取现金”用例的后置条件为:当用例结束时,所有帐户和交易日志都已收支平衡,与银行业务系统的通信已重新初始化,并且银行卡已经返还给客户。
扩展点使用例具有了扩展的可能性。一个扩展点有一个名称和一系列对用例事件流中一个或多个位置的引用。一个扩展点可以引用用例内的两个行为步骤之间的单个位置。它也可以引用一组不连续的位置。
使用已命名的扩展点将有助于将扩展用例的行为规约从基本用例的内部细节中分离出来。您可以对基本用例进行修改或重新整理,只要扩展点的名称保持不变,那么这种变更将不会影响扩展用例。同时,您不用在说明基本用例事件流的文本中包括有关行为可能在何处扩展的细节。请参见指南:扩展关系。
示例:
在电话系统中,可以由抽象用例“显示呼叫方身份”来扩展用例“打电话”。这是一项可选服务,通常称为“呼叫方 ID”,接收方可能已请求该服务,也可能还未请求。用例“打电话”中扩展点的说明可能如下所示:
名称:显示身份
位置:在“1.9 节:使接收方的电话振铃”之后。
您可能会选择在一个用例图(在很少的情况下会需要多个用例图)中阐明一个用例(用例图属于该用例)与主角以及其他用例的关系。如果用例涉及到许多主角,或者与很多其他用例有关系,那么用例图将非常有用。由于这种图只是从一个用例的角度来显示用例模型,而不用于解释整个用例模型的一般事实,所以它具有“局部”特征。另请参见指南:用例图。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。