用例模型
系统既定功能及系统环境的模型
用例模型是系统既定功能及系统环境的模型,它可以作为客户和开发人员之间的契约。用例是贯穿整个系统开发的一条主线。同一个用例模型即为需求工作流程的结果,可当作分析设计工作流程以及测试工作流程的输入使用。
建模介绍
系统建模有许多种方法,每种建模方法可以满足不同的目的。然而,用例模型最重要的作用是将系统行为传达给客户或最终用户。因此,模型必须易于理解。
用途说明
可能与该系统交互的用户和任何其他系统都是主角。由于主角代表了系统用户,它们协助界定系统并提供十分明确的系统用途说明。编写用例依据主角的需求来进行。这样就确保该系统成为用户期望得到的系统。
用例模型如何演进
主角和用例都是通过将客户需求潜在用户当作重要的信息查找到的。找到这些用例和主角后,应对它们作简要说明。在详细说明这些用例之前,客户应复审该用例模型以核实所有的用例和主角都已经找到,并且它们可以提供客户所需要的东西。
在迭代开发环境中,您可以选择用例的子集以便在每个迭代中详细描述。另请参见活动:确定用例的优先级
主角和用例找到后,需要详细说明每个用例的事件流。这些说明指出系统与主角交互的方式以及在各个独立用例中系统执行的有关操作。
最后,对已完成的用例模型(包括用例说明)进行复审,开发人员和客户使用该模型对系统应执行的操作达成一致意见。
用例模型退化导致系统功能分解的情况并不罕见。为避免发生这种情况,必须注意以下故障现象:
“小”用例,即对事件流的说明只有一个或少数几个句子。 “许多”用例,即用例的数量有好几百,而不是好几十。 用例名的构造类似于“根据这一特定数据执行本操作”或“利用这一数据执行本功能”等。例如,“在 ATM 机上输入个人识别号”不应建模为 ATM 机的一个单独用例,原因是没有人会使用系统仅执行这一操作。用例是一个完整事件流,它可以产生对主角有价值的东西。
为避免功能分解,您需要确保该用例模型有助于回答诸如以下的问题:
系统的环境是什么? 为什么要建立系统? 用户在使用系统时希望获得什么? 系统将给用户创造什么价值?
不难发现,用例是一个很好的获取系统功能性需求的方法。但是对于非功能性需求,情况又如何呢?什么是非功能性需求,可以在何处获得它们?
非功能性需求通常分为可用性需求、可靠性需求、性能需求以及可替换性需求(另请参阅概念:需求)。它们通常是指定需要符合任意法律法规要求的需求。它们也可以是由于所使用的操作系统、环境平台、兼容性或所采用的任何应用标准等问题产生的设计约束。通常,任何不允许有一个以上设计选项的需求都可以认为是一个设计约束。
许多非功能性需求适用于一个单独的用例,并且可以在该用例的特征内获得这些需求。在这种情况下,这些需求可以在用例的事件流内获取,或者作为用例的一个特殊需求来获取(请参阅指南:用例)。
示例:
在回收机系统中,返还储存项用例的一个特定非功能性需求是:该机器识别储存项的可靠性必须高于 95%。
通常,功能性需求适用于整个系统。此类需求可以在补充规约中获得(请参阅工件:补充规约)。 示例:
在回收机系统中,一个适用于整个系统的非功能性规约是:
机器每次只允许一个用户使用。
内容与方式的两难局面
学习如何确定用例应该在哪个明细级别上“开始和结束”是一件比较困难的事情。特征和用例开始于何处,而用例结束和设计开始又在什么地方?我们通常说,用例或软件需求应该规定系统做“什么”而不是“如何”做的问题。以下图为例:
一个人的终点是另一个人的起点。
根据个人背景,您可以使用不同的环境来确定您对“什么”以及“如何”的理解。当决定是否应该将某个细节摈弃于用例模型之外时,需要仔细考虑这一问题。
具体用例和抽象用例
具体用例和抽象用例之间存在一个区别。具体用例由主角来启动,并且构成一个完整的事件流。“完整”意味着该用例的一个实例执行由主角调用的全部操作。抽象用例本身从来不会被实例化。抽象用例包括在(请参阅指南:包含关系)其他用例中,扩展到(请参阅指南:扩展关系)或泛化关系(请参阅指南:用例泛化关系)其他用例。在启动一个具体用例时,也就创建了该用例的一个实例。这一实例还展示了由其关联关系的抽象用例指定的活动。因而,从抽象用例中无法创建单独的实例。
由于主角在系统中“看见”和启动的是具体用例,因此这两种用例之间的区别非常重要。
表明一个用例为抽象用例时,可以将其名称格式设置为斜体。示例:
“创建任务”用例包括在“注册单”用例中“创建任务”用例是一个抽象用例。
在库房管理系统中,“创建任务”抽象用例包括在“注册单”用例中。启动“注册单”用例后,将创建一个注册单实例。该实例除了遵循注册单的事件流之外,它还遵循在所包含的用例“创建任务”内说明的事件流。“创建任务”本身从来不被执行,但始终作为“注册单”(或其他任何包含“创建任务”的用例)的一个部分。因此,“创建任务”是一个抽象用例。
构建用例模型
构建用例模型有三个主要的原因:
使用例更易于理解。 将在许多用例内说明的公有行为分离出来。 使用例模型更易于维护。
然而,构建模型并不是首先要做的事情。在您对用例的行为有更深入的了解(而不是一句话简要说明)之前,千万不要构建该用例。您至少需要为该用例的事件流建立一个分步说明大纲,确保您的决策是建立在对该行为有精确而充分的理解基础之上。
有三种关系可以用于构建用例。您可以使用这些关系来分析出用例部件,这些部件可以在其他用例中复用,或者作为该用例的特例或选项。表示修改的用例称为附加用例。被修改的用例称为基本用例。
如果基本用例中有一部分功能,该用例的执行与否由它的结果决定,而不是由产生该结果的方法来决定,则可以将这一部分功能分离出来,放到一个附加用例中。采用包含关系,可以将附加用例显式插入基本用例中。另请参见指南:包含关系。
如果基本用例的一部分是可选的,或对于理解该用例的主要目的来说不是必需的,那么您可以将这部分分离出来,形成一个附加用例,以简化基本用例的结构。利用扩展关系,可以将附加用例隐式插入基本用例中。另请参见指南:扩展关系。
如果用例在行为和结构上具有共同点而且在目的上又很相似,则可以将它们的共同部分分离出来,形成一个基本用例(父用例)。而附加用例(子用例)可以继承该父用例。子用例可以在从父用例继承的结构中插入新的行为或修改现有的行为。另请参见指南:用例泛化关系。
您可以使用主角泛化关系来显示主角之间的特化情况。另请参见指南:主角泛化关系。
示例:
订单管理系统的用例模型部分为例进行说明。
由于他们具有略微不同的特征,因此将普通客户从 Internet 客户中分离开来是非常有用的。然而,因为 Internet 客户的确显示了一个客户具有的所有特征,所以您可以说 Internet 客户是客户的一个特例,并且能够通过主角泛化关系来指示。
在本图中,具体用例分别是“电话订购”(由客户主角发出)和“Internet 订购”(由 Internet 客户发出)。这些用例都是更普通的“??一个抽象用例。“请求目录”用例代表一个可选行为段,它不是“订购”用例主要目标的组成部分。它已经被分离出来,形成了一个抽象用例,用于简化“订购”用例。“提供客户数据”用例是一个已分离出的行为段。它之所以被分离出来,是因为它是一个独立功能,只有它的结果才能影响“订购”用例。“供给客户数据”用例还可以在其他用例中复用。“请求目录”用例和“供给客户数据”用例在本示例中都属于抽象用例。
用例图显示订单管理系统的用户模型部分。
下表显示了三个不同用例关系之间更详细的比较:
为达到更易于理解的目的,组织用例模型的另一个方法是对用例进行分组,形成多个包。用例模型可以组织为一个有层次的用例包结构,而主角或用例是该结构中的“树叶”。另请参见指南:用例包。本图显示用例模型的分层结构。箭头表示可能存在所有权关系。
用例是否始终和主角有关
每个用例的执行都包含与一个或多个主角的交流。用例实例始终通过主角要求系统执行某些任务来启动。这意味着每个用例需要与主角建立通信关联关系。此规则的理由是强迫系统只提供用户需要的功能,而不提供任何其他的东西。如果存在无人请求的用例,则表明在该用例模型或需求中存在错误。 然而,此规则也有一些例外情况: 如果用例是抽象的(不是可独立实例化的),则其行为可能不包括与主角的交互。这种情况下,将不存在任何从该抽象用例到主角的通信关联关系。 如果父用例说明了所有的主角通信,则泛化关系中的子用例不需要与主角相关联。 如果包含用例说明了所有的主角通信,则包含关系中的基本用例不需要与主角相关联。 一个用例可能按照时间表(例如,一星期一次或一天一次)来启动,这意味着系统时钟即为启动程序。由于用例不是由主角而是由内部系统事件启动的,因此系统时钟对于该系统而言是内在的。如果在该用例中没有发生其他的主角交互,则它与主角之间不存在任何关联关系。然而,为了清楚起见,您可以在用例图中使用一个虚构的主角“时间”来显示该用例是如何启动的。
调查说明
用例模型 的调查说明应该: 声明哪些是系统的主要用例(系统建立的原因)。 总结有关系统的重要技术实际情况。 指出系统定界 - 系统将不执行的操作。 概述系统的环境,例如目标平台和现有的软件。 描述在该系统中正常执行用例的任意序列。 详细说明用例模型未处理的功能。 示例: 以下是关于回收机的用例模型的调查说明示例: 本模型包括三个主角和三个用例。主要用例是“回收项”,它说明回收机的主要用途。 支持用例有: “打印日常报告”,操作员可以使用它获得关于已经回收多少项目的报告。 “管理储存项”,操作人员可以使用它来变更某个储存项类型的退款金额,或增加新的储存项类型。
参考资料
最新修订时间:2023-12-28 17:13
目录
概述
建模介绍
用途说明
参考资料