本文内容
阅读须知:
- 本文对用例图的介绍包含个人见解,如有不妥之处,请不吝赐教。
本文将介绍:
- 何为用例
- 如何编写用例
- 何为用例图
- 如何制作用例图
用例
定义
维基对用例的定义如下:
用例是一个行动或事件步骤的列表。
其通常是一个角色(在统一建模语言(UML)中被称为Actor)和一个系统之间的互动,以实现一个目标。行为者可以是人或其他外部系统;用例通常代表任务或利益相关者的目标。
更详细的需求可以被记录在系统建模语言(SysML)中,或者作为合同声明。
可以归纳出:
- 用例的两个端点分别是角色和目标
- 用例用于描述系统的任务目标,而非用作功能分解
模板
用例编写有诸多方法,详略多变,模板也多种多样。但如果使用专家设计的模板编写用例,更易得到高质量的系统需求描述。
科伯恩(Cockburn)风格
Alistair Cockburn在 Writing Effective Use Cases 一书中定义的模板
目标级别
Cockburn建议在每个用例上标注一个符号,以显示 “目标级别”,首选的用例级别是 “用户目标”
目标级别 | 符号 | 图标 |
---|---|---|
高度概括 | ++ | 云彩 |
概括 | + | 风筝 |
⭐用户目标 | ! | 海浪 |
子功能 | - | 鱼 |
底层实现 | – | 海底蛤蜊 |
下面这个例子展示了系统各层级目标所处的目标级别:
观察用户目标层不难发现,用例之所以首选这层,是因为目标粒度恰到好处:
- 首先它实打实反映了用户的目标与需求
- 此层往下,则是一些琐碎的模块实现
- 此层往上,是一些高度抽象的概念
详述用例
Cockburn描述了一个究极详细的用例结构(但可按需简化)。他的完整用例模板列出了以下字段:
- 标题 (Title):一个描述角色目标的动词目标短语
- 主要角色 (Primary Actor)
- 目标 (Goal in Context)
- (目标)作用范围 (Scope)
- (目标)级别 (Level)
- 利益相关者和利益 (Stakeholders and Interests)
- 前提条件 (Precondition)
- 最低保证 (Minimal Guarantees)
- 成功保证 (Success Guarantees)
- 触发条件 (Trigger)
- 主要成功情景 (Main Success Scenario
- 扩展 (Extensions)
- 技术和数据变更表(Technoloy & Data Variations List)
简要用例
Cockburn意识到不是所有项目都需要如此重量级的用例,他又给出了一个轻量级的用例模板:
- 标题(即作目标)
- 主要角色
- 作用范围
- 级别
- 简述:用一两段文字简要描述该用例的执行流程与结果等
福勒(Fowler)风格
Martin Fowler指出:“编写用例没有标准的方法,各有千秋”。他描述 "可通用的用例风格 "如下:
- 标题:用例所要满足的目标
- 主要成功情景:带编号的步骤列表
- 步骤:行为者和系统之间互动的简单陈述
- 扩展:每个扩展用一个单独编号的列表表示
- 具体扩展:指"一个导致‘主要成功情景’中某处结果发生变化的条件"。(主步骤3的首个扩展应被编号为3a,以此类推……)
例子
下面是一个用Cockburn模板稍加修改后编写的用例。值得注意的是,在用例描述中没有出现按钮、控件、表单或任何其他UI元素和操作;在基本流程(Basic flow)或扩展(Extensions)的每一步中,只表达了用户目标、子目标或意图。这种做法使需求说明更加清晰,并使设计和实现的灵活性最大化。
-
用例:文章编辑
-
主要角色:注册用户
-
作用范围:Wiki系统
-
级别:!(用户目标)
-
简介:
成员编辑他们正在阅读的文章的任何部分。在编辑过程中预览和对比修改。 -
利益相关者:
(略) -
后置条件:
- 最低保证:
- 成功保证:
文章正常保存,并显示更新的视图。
系统创建文章的编辑记录,因此文章的审核者可以在以后被告知更新。
-
前提条件:
启用编辑功能的文章展示给该成员。 -
触发条件:
该成员对该文章发出编辑请求。 -
基本流程:
- 系统提供一个新编辑区,里面有文章的所有相关内容,并有一个信息丰富的编辑摘要供会员编辑。如果会员只想编辑文章的某一章节,则只显示该章节的原始内容,章节标题会自动填写在编辑摘要中。
- 成员修改文章的内容,直到其满意为止。
- 成员填写编辑摘要,告诉系统这篇文章已被更改,并提交编辑。
- 系统保存文章,记录编辑事件并完成任何必要的后期处理。
- 系统将文章的更新视图呈现给成员。
-
扩展:
2-3.
a. 显示预览- 会员选择 “显示预览”,提交修改后的内容。
- 系统重新运行步骤1,增加渲染更新的内容进行预览,并通知会员他/她的编辑还没有被保存,然后继续。
b. 显示修改
- 会员选择 “显示修改”,提交修改后的内容。
- 系统重新运行步骤1,增加显示比较会员当前编辑的内容与文章最新保存版本之间的差异的结果,然后继续。
c. 取消编辑
- 会员选择 “取消”。
- 系统放弃该会员所做的任何修改,然后进入步骤5。
4a.超时
……
选择好用例
虽说任何一个目标都可用作用例,但用例本身是用于描述系统整体目标的,因此如何选择合适的用例对系统整体描述非常有帮助。
前文说到,最好的用例应该是用户目标。我们应该放在用户的角度考虑,用户会去做什么:
建议一:选取具体目标
这是确定用例粒度上界的原则。
用例应是具体到单个具体行为的目标,而非是高度抽象的概念(但如果系统规模较大,为简化问题是可以选择更抽象的行为的),否则用例对系统的描述就非常笼统了。
建议二:选取有效目标
这是确定用例粒度下界的原则。
意思是用户会愿意仅单独完成这个目标,然后离开系统,否则这个用例是非常琐碎繁杂的。
思考:登录是好的用例吗?
许多人会把登录当作一个用例,但事实上这并不是好做法。
因为没有用户会愿意登录系统之后,就马上离开系统。用户登录肯定是有目的的,而这个潜在目的才是用户真实的行为目标,也是我们所寻求的合适用例。
登录属于Cockburn模型中的“子功能目标”,因此这是对具体功能的分解,不应该作为用例。
用例图
何为用例图
用例图不像用例一样有明确的定义或规则,我们应该自行思考何为用例图。
从用例出发
综合系统中所有用例,归纳成图,即为用例图。
没错,最初,或者说最正统的用例图就是一个“用户–>目标”的单层次的结构,它并不能以多层形式表示结构间的关系,因此,下面这个例子就是一个正统(撇开登录用例不谈)用例图:
但是实际软件工程使用中,这样的用例图过于单调,有时我们确实希望在其上面做一些模块化的规划,即使这会引入一些非优选的“子功能”用例结点。
从应用出发
实际应用中的用例图是传统用例图的超集。
我们希望用例图对系统功能的描述更细致一些,因此在原始的用例图上,增加了多种多样的结点。这些用例图的变体没有对错之分,各类结点有自身的作用,但此处,只介绍使用较常见的3种增强结点。
增强结点
include关系
include结点的定义众说纷纭,莫衷一是,但最常见的定义为:
include结点表示完成用例必定执行的过程。即用例“主要成功情景”部分涉及的子过程。
记为:
例如,为自动贩卖机放置饮料,必须先打开机器:
注意:此处打开机器和关闭机器本身并不是合适的用例,但出于强调作用在include结点出现是可接受的,这使系统描述更加清晰。
extend关系
extend最常见的定义为:
extend表示完成用例时条件触发的过程。即用例“扩展”部分涉及的过程。
记为:
例如:图书馆还书,仅在逾期时触发罚款用例:
泛化关系
子用例继承了父用例所有的结构、行为和关系,是父用例的一种特殊形式。
结点滥用
include结点指的是过程包含,而非功能包含。像如下这种是常见的不规范做法:
管理功能包含增加、删除、修改功能
-
“管理”学生,不见得每次执行管理,就必须涵盖“添加”、“删除”、“修改”这三个过程。我可以只执行其中一部分,因此这3个结点不是管理所必须的,就不应该放入include结点中。
-
放入extend结点中似乎是合理。但“扩展”是相对于“主要成功情景”的,扩展的前提是与成功情景产生分歧,然而这3个功能它并不跟主要成功情景冲突。
-
放在哪个结点都并不合适,最合理的解释是:这个做法本身就是错误的。
文章开始已经提到,用例图是用于描述系统整体功能,而非用于分解问题的。
这个做法显然是企图在用例图上分解问题。虽然增强结点给予了用例图一定分解的能力,但它们始终是辅助功能,并非所有分解都能通过这些结点表示;而且,用例图本就不应出现分解,增强结点只应在特别需要强调的情况下使用,而不应滥用。
怎么解决这个问题?
很简单,只留下“管理”单个用例;或者“增加”、“删除”、“修改”三个用例。
具体留下哪个,需要根据系统规模决定:
-
系统规模小,肯定是首选后三个代表用户目标的用例;
-
系统规模大,三个用例就略显繁琐,此时应考虑代表概括目标的管理用例。
画好用例图
按以下步骤,画用例图将事半功倍。
- 编写用例
- 罗列系统功能,必要时画成Cockburn目标级别图
- 归纳出系统中的所有角色,为每个角色:
- 挑选出处于“用户目标”层的用例
- 统计用例数量,根据系统规模权衡:是否需要用其它层的用例代替现有用例
- 用例的数量不宜过多或过少
- 用例需要能够描述系统功能或目标
- 选择或制定用例模板,编写用例
- 重新审视每个用例,确保所有用例都是“好用例”
- 画用例图
- 画出所有角色和用例
- 根据编写的用例,连接角色和用例结点
- 考虑每个用例的“扩展”部分,将其中重要的过程、用例作为extend结点添加至用例图
- 考虑每个用例,将需要特别强调的要点以“include结点”、“泛化结点”……的形式添加至用例图
- 重新审视用例图,若其规模不太妥当,考虑增加或删掉一些增强结点
- 将用例及用例图整合至同一文档