跳到正文

用例图示例:参与者、用例、include 与 extend

通过一个完整示例讲解用例图:参与者、用例和系统边界的 UML 记法,include 与 extend 的区别,用例描述和常见错误。

· 创始人兼开发者

发布于

一个标为 Food ordering app 的矩形中有七个椭圆:Browse menu、Place order、Pay for order、Apply promo code、Track delivery、Accept order 和 Deliver order。左侧是 Customer、Restaurant staff 和 Courier 三个参与者,右侧是 Payment provider 参与者。

用例图在一页纸上回答一个问题:谁在使用这个系统,用它做什么?产品经理用它来对齐范围,工程师用它来看清系统的每一个入口,测试人员用它来确认每个目标都有对应的路径。它也是最常被画错的 UML 图之一:有人把它画成流程图,有人把每个按钮都画成一个用例,还有人把 include 和 extend 用反了。

本文按照 UML 2.5.1 规范的定义讲解记法,用一个简单的测试厘清 include 与 extend,完整走一遍订餐应用的示例,展示每个椭圆背后应有的文字描述,并列出让用例图失去价值的常见错误。

记法

元素 符号 含义
参与者 带名字的小人 与系统交互的角色:人、另一个系统或时间
用例 写有动词短语的椭圆 参与者借助系统达成的目标
主题(系统边界) 写有系统名称的矩形 哪些在系统内,哪些在系统外
关联 实线 参与者参与该用例
包含(include) 标有 «include» 的虚线箭头,从基础用例指向被包含的用例 基础用例总会执行被包含的行为
扩展(extend) 标有 «extend» 的虚线箭头,从扩展用例指向基础用例 在特定条件下附加到基础用例上的可选行为
泛化 父元素一端带空心三角形的实线 特化的参与者或用例

箭头方向直接来自 OMG 于 2017 年 12 月发布的 UML 2.5.1 规范:include 从基础用例指向被包含的用例;extend 从扩展用例指向它所扩展的用例。规范还允许使用扩展点,即基础用例中可以接入扩展的具名位置,列在椭圆内部。

include 与 extend:一个测试

问一问:没有另一个用例,基础用例是否完整?

  • 没有它就不完整:include。 下单总要付款。“Place order”包含“Pay for order”。箭头指向被包含的用例,基础用例离开它无法执行。
  • 没有它也完整:extend。 使用优惠码是可选的,没有优惠码的订单同样完全有效。当顾客有优惠码时,“Apply promo code”在“付款前”这样的扩展点上扩展“Place order”。箭头指向基础用例,而基础用例甚至不知道扩展的存在。

另外两条规则能避免大多数误用:

  • 用 include 来共享多个用例都需要的行为,例如身份验证或支付。不要用它把一个用例拆成若干步骤,那是流程图。
  • 谨慎使用 extend。如果 extend 比基础用例还多,你记录的是界面选项,而不是目标。

参与者是角色

参与者是角色,而不是某个人或职位。同一个人可以上午是顾客,下午是餐厅经理。参与者也可以是系统:应用为了授权银行卡而调用的支付服务商就是一个辅助参与者。有些团队用一个“Time”参与者来表示定时任务,这是一种常见约定,适用于没有人手动发起的用例。

按照惯例,为达成自身目标而发起用例的主要参与者放在左侧,系统所依赖的辅助参与者放在右侧。

在合适的层级为用例命名

从参与者的视角,用动词加宾语为用例命名:叫“下单”,而不是“订单”“订单页面”或“提交按钮”。每个用例都应该是参与者一次就能完成、并且乐于达成的目标,Alistair Cockburn 称之为用户目标的海平面层级。更高的层级(“经营餐厅”)对一个椭圆来说太宽泛;更低的层级(“输入卡号”)则是用例内部的步骤。

完整示例:订餐

下图展示一个有四个参与者的订餐应用:

  • Customer 浏览菜单、下单并跟踪配送。
  • Restaurant staff 接单。
  • Courier 配送订单。
  • Payment provider 是外部系统,为支付提供支持。

边界内有七个用例:

  1. Browse menu
  2. Place order,包含 Pay for order
  3. Pay for order,由支付服务商提供支持
  4. Apply promo code,在付款前扩展 Place order
  5. Track delivery
  6. Accept order
  7. Deliver order

注意图中没有的东西:没有步骤顺序,没有页面,也没有给每个参与者都画一个“Log in”椭圆。身份验证是前置条件,而不是目标;它应写在用例描述里,只有当它包含实际行为时,才作为一个被包含的用例出现。

每个椭圆背后的描述

图只是索引,真正的价值在于每个用例的简短描述,例如:

Use case: Place order
Primary actor: Customer
Precondition: The customer is signed in and the basket is not empty.

Main success scenario:
  1. Customer reviews the basket and delivery address.
  2. System shows the total, including fees and estimated delivery time.
  3. Customer confirms the order.
  4. System takes payment (includes: Pay for order).
  5. System sends the order to the restaurant and confirms it to the customer.

Extensions:
  2a. Customer has a promo code: Apply promo code, then continue at step 2.
  4a. Payment is declined: System asks for another payment method.
  5a. Restaurant does not accept within 5 minutes: System cancels and refunds.

Postcondition: The order is paid and visible to the restaurant.

描述中的扩展,也就是那些编号的“如果……怎么办”分支,正是需求和测试用例的来源。它们比图上的 extend 关系详细得多,图上只应画出值得用图形表达的可选目标。

常见错误

  • 伪装成用例图的流程图。 用例之间表示“然后”的箭头会把图变成流程模型。表达工作顺序请用 BPMN 图或活动图。
  • 每个 CRUD 操作一个用例。 “新建菜品”“修改菜品”和“删除菜品”通常是同一个目标:“管理菜单”。
  • 把页面和按钮当成用例。 “点击结算”是步骤,不是目标。
  • 用 include 做分解。 如果每个用例都包含另外三个用例,这张图描述的是代码结构,而不是用户目标。
  • 把内部组件当成参与者。 数据库不是参与者,它在系统内部。你调用的外部系统才是。
  • 没有边界。 没有主题矩形,读者就分不清你在构建什么、又依赖什么。

用例图、用户故事与时序图

用例图 用户故事 时序图
回答的问题 谁用系统做什么 接下来构建什么,按小块切分 在一个场景中各部分如何交互
粒度 用户目标 价值增量 参与者之间的消息
最适合 范围、入职培训、测试覆盖 待办事项规划 设计与调试

三者相辅相成:用例图描绘全貌,用户故事把它切成可交付的小块,而时序图展示某个场景实际如何运行。

用例图

一个标为 Food ordering app 的矩形中有七个椭圆:Browse menu、Place order、Pay for order、Apply promo code、Track delivery、Accept order 和 Deliver order。左侧是 Customer、Restaurant staff 和 Courier 三个参与者,右侧是 Payment provider 参与者。

13 个组件 · 8 个连接

在 Archboard 中打开
图表内容
  • Food ordering app
  • Customer
  • Restaurant staff
  • Courier
  • Payment provider
  • Browse menu
  • Place order
  • Track delivery
  • Pay for order
  • Apply promo code
  • Accept order
  • Deliver order
  • «include»
  • «extend» [has a promo code]
一个订餐应用的用例图。顾客、餐厅员工和骑手出于不同目标使用系统;下单总是包含支付,优惠码可选地扩展下单,支付服务商为支付用例提供支持。

这张图的读法如下:

  • 矩形是系统边界:里面的一切都属于订餐应用。
  • 左侧的参与者发起用例:顾客有三个目标,餐厅员工和骑手各有一个。
  • 右侧的支付服务商是应用在支付时调用的辅助系统。
  • 从 Place order 指向 Pay for order 的 «include» 箭头表示支付一定会发生。从 Apply promo code 指向 Place order 的 «extend» 箭头表示优惠码是可选的。
  • Markdown 块是给初学 UML 的读者看的记法说明。

画出真正有人读的用例图

  • 每张图大约不超过 15 个用例。 如果系统更大,就按参与者或子系统拆分。
  • 主要参与者放左边,辅助参与者放右边,让阅读方向与发起顺序一致。
  • 明确标注 include 和 extend,带上书名号式的双尖括号,箭头保持虚线。
  • 细节留给用例描述。 图应该能放进一张幻灯片,文字则可以按需要写长。

用例图可以与其他 UML 视图搭配使用:领域模型可参考 UML 类图示例,订单的生命周期可参考状态图示例。

在 Archboard 中构建

  1. 使用 Google 或 GitHub 登录,并新建一张图。
  2. 添加一个名为 Food ordering app 的基础 框架,作为系统边界。
  3. 在框架内添加七个 UML 节点包中的 用例 节点,按上文命名。
  4. 添加四个 UML 节点包中的 参与者 节点:左侧放 Customer、Restaurant staff 和 Courier,右侧放 Payment provider。
  5. 用普通线条把参与者连接到各自的用例。添加两条虚线连线:一条从 Place order 指向 Pay for order,标注 «include»;另一条从 Apply promo code 指向 Place order,标注 «extend»。
  6. 添加一个基础节点包中的 Markdown 块,写上简短的记法说明。

这个示例共用 13 个图表节点,在 Free 套餐的限制之内。

常见问题

用例图中 include 和 extend 有什么区别? include 表示基础用例总会执行被包含的行为,箭头指向被包含的用例。extend 表示在特定条件下附加的可选行为,箭头从扩展用例指向基础用例。

参与者可以是系统吗? 可以。任何与系统交互的外部角色都可以是参与者,包括支付服务商这样的其他软件。你系统内部的组件不是参与者。

参与者和用例之间应该用箭头连接吗? UML 在参与者和用例之间使用普通的关联线。有些团队会加上箭头来表示由谁发起,但标准记法并不要求这样做。

一张图应该有多少个用例? 作为参考,大约不超过 15 个。更大的系统拆成几张图会更易读,可以按参与者或子系统划分。

用例图会展示步骤的顺序吗? 不会。它们展示的是目标,而不是顺序。步骤顺序应写在用例描述、活动图或时序图中。

免费开始 — 1 个席位,无需信用卡。

相关文章

← 返回博客

一分钟打开画布

使用 Google 或 GitHub 登录。单席位免费,团队加入后再升级。