使用 UML 建模现实世界需求——实用指南
1. 引言
在现代软件开发中,用例图是从用户角度捕获功能需求的基础工具。本案例研究对一个现实用例图进行了详细分析,该图针对外卖平台,采用PlantUML 语法作为建模语言。目标不仅是展示哪些元素被用于图中,而且还要展示为何它们被选中——重点突出实用的建模决策, 惯例以及常见陷阱.
本案例研究既服务于学习 UML 的初学者,也服务于正在完善建模实践的从业者。它分解了图中的每个元素,解释其用途,并讨论现实世界的影响。
2. 系统概述
该外卖平台是一个连接以下各方的数字市场:
- 顾客(订购食物的个人),
- 餐厅(餐食提供方),
- 配送员(配送人员),
- 外部支付网关(处理交易的外部系统)。
该平台使用户能够浏览餐厅、下单、追踪配送、管理支付以及应用促销活动。该系统与支付处理商等外部服务集成,但不内部处理支付逻辑。
PlantUML 代码:
@startuml
skinparam monochrome true
skinparam shadowing false
left to right direction
' 所有参与者均在矩形外部定义
actor Customer
actor "Registered Customer" as RegCustomer
actor "Restaurant Staff" as Restaurant
actor Driver
actor "Payment Processor" as PaymentGW
rectangle "Food Delivery Platform" {
(Browse Restaurants)
(Place Order)
(Track Order)
(Manage Menu)
(Accept / Prepare Order)
(Deliver Order)
(Process Payment)
(Issue Refund)
(Apply Promo Code)
(Use Wallet)
(Card Payment)
(Digital Wallet Payment)
' 关联关系——箭头跨越边界
Customer --> (Browse Restaurants)
RegCustomer --> (Place Order)
RegCustomer --> (Track Order)
Restaurant --> (Manage Menu)
Restaurant --> (Accept / Prepare Order)
Driver --> (Deliver Order)
PaymentGW --> (Process Payment)
PaymentGW --> (Issue Refund)
' 包含关系
(Place Order) ..> (Process Payment) : <<include>>
' 扩展关系
(Place Order) <.. (Apply Promo Code) : <<extend>>
(Process Payment) <.. (Use Wallet) : <<extend>>
' 泛化关系
(Process Payment) <|-- (Card Payment)
(Process Payment) <|-- (Digital Wallet Payment)
}
' 参与者泛化(也在外部)
Customer <|-- RegCustomer
note right of PaymentGW
外部支付网关
(Stripe, PayPal, Adyen, ...)
end note
note bottom of (Apply Promo Code)
可选——仅在输入有效代码时适用
end note
@enduml ✅ 关键洞察:该图侧重于外部交互——它展示系统为其用户和系统所做的事情,而非其实现方式。
3. 图表元素:深入解析与实际含义
以下是图中所用每个 UML 元素的全面解析,包括现实世界的解释与建模理由。
| # | 元素 | 符号 | 含义与目的 | 建模决策/注释 |
|---|---|---|---|---|
| 1 | 系统边界 | 矩形“外卖平台” |
定义范围的建模系统。内部所有用例均属于该系统。 | 名称应简洁且具有描述性。在企业环境中,可使用较长的名称(例如“客户订单管理系统”)。 |
| 2 | 主要人类参与者 | 参与者 客户, 参与者 配送员 |
表示外部角色,这些角色发起或参与用例。 | 名称应简单直观。避免使用不必要的构造型,例如<<person>>,除非大型模型需要。 |
| 3 | 带别名的参与者 | 参与者“餐厅员工”别名为 Restaurant |
允许将较长且具有描述性的参与者名称缩短,以提高连接关系的清晰度。 | 当参与者名称包含空格或过于冗长时尤为有效。可减少杂乱并提高可读性。 |
| 4 | 外部系统参与者 | 参与者“支付处理器”别名为 PaymentGW |
建模第三方系统,平台与其进行交互。 | 无需构造型«system»被使用——在轻量级图中是可接受的。然而,添加”«系统»可以阐明复杂系统中的意图。 |
| 5 | 参与者泛化 | `客户 < | — 注册客户` | 表示一个注册客户是访客客户. |
| 6 | 普通关联 | 客户 --> (浏览餐厅) |
表示该参与者发起或参与该用例。 | 实线 = 通信。方向隐含从参与者到用例(无需箭头)。 |
| 7 | «包含»关系 | (下订单) ..> (处理支付) : <<包含>> |
处理支付是始终必需在下订单时。 |
箭头指向从包含者指向被包含者。这一点至关重要:下订单 包含 处理支付 作为必要步骤。 |
| 8 | «扩展»关系 | (下订单) <.. (应用促销代码) : <<扩展>> |
应用促销代码是 可选的 且仅在特定条件下发生。 | 箭头指向 从扩展 → 基础。基础用例(下订单)可以被扩展 有条件地. |
| 9 | 用例泛化 | `(处理支付) < | — (卡支付)<br>(处理支付) < |
— (数字钱包支付)` |
| 10 | 注意 | 在 PaymentGW 右侧的注释在(应用促销代码)下方的注释 |
提供 上下文解释关于实现或业务规则。 | 注释常被低估,但极其有价值。它们可防止误解(例如,明确 PaymentGW 是外部系统)。 |
| 11 | 边界外的参与者 | 所有参与者声明应位于矩形之前 |
强调没有任何参与者属于系统内部——职责清晰分离。 | 两种标准布局之一。当参与者数量众多或为外部实体时,推荐使用此布局。 |
| 12 | 图表方向 | 从左到右的方向 |
当多个参与者位于左侧时,可优化布局。 | 提升可读性。在 4 至 8 个参与者时效果尤为显著。替代方案:参与者较少时可采用自上而下的布局。 |
4. 关键建模决策与理由
✅ 为何参与者位于系统边界之外
- 最佳实践:参与者代表系统外部的角色。
- 为何重要:可避免系统组件与外部实体之间的混淆。
- 示例:
驾驶员不是平台的一个模块——它们是与之交互的第三方角色。
📌 专业提示:如果所有参与者都在边界内,则意味着系统包含了它们——这具有误导性。
✅ 为何使用Customer <|-- RegCustomer而不是重复链接
- 若无泛化,您必须绘制:
PlantUML Edit PlantUML in VPasCode
Customer --> (浏览餐厅) RegCustomer --> (浏览餐厅) RegCustomer --> (下订单) - 若有泛化,您只需:
PlantUML Edit PlantUML in VPasCode
Customer <|-- RegCustomer Customer --> (浏览餐厅) RegCustomer --> (下订单) - 结果:更清晰、更易维护的图表。
📌 最佳实践:每当专用参与者继承更通用参与者的所有行为时,请使用参与者泛化。
✅ 为何<<include>>和<<extend>>被正确使用
| 关系 | 目的 | 方向 | 示例 |
|---|---|---|---|
<<包含>> |
强制子流程 | 来自 包括 → 已包含 | 下订单 必须 包含 处理支付 |
<<扩展>> |
可选扩展 | 来自 扩展 → 基础 | 应用促销码 扩展 下订单 仅当代码有效时 |
❗ 常见错误: 箭头方向反转。请始终记住:
包含:基础 ..> 已包含扩展:扩展 <.. 基类
✅ 为什么 处理支付具有一般化关系
卡支付和数字钱包支付是 专用形式的处理支付.- 这表明该平台支持 多种支付方式,但它们都遵循相同的核心流程。
- 一般化支持 共享行为和 未来的可扩展性.
📌 用例:添加新的支付方式(例如 Apple Pay)只是对
处理支付.
5. 现实世界解读与问题解答
该图表不仅是一种视觉辅助工具——它还回答了关键的业务和技术问题:
| 问题 | 来自图表的答案 |
|---|---|
| 主要用户是谁? | 顾客、注册用户、餐厅员工、司机、支付网关 |
| 未注册用户能下单吗? | ❌ 否 — 仅注册用户可以下单. 顾客仅能浏览餐厅. |
| 是否总是需要付款? | ✅ 是 — 下单 包含 处理付款。强制性。 |
| 顾客可以应用促销代码吗? | ✅ 是 — 但仅可选地通过<<扩展>>。仅当输入有效代码时。 |
| 支持哪些支付方式? | 银行卡和数字钱包(通过泛化)。实际处理由外部系统负责。 |
| 谁负责处理付款? | 外部支付网关——不属于平台的一部分。 |
| 餐厅能否管理其菜单? | ✅ 是——餐厅参与者与管理菜单和接受/准备订单. |
✅ 业务价值:该图清晰地传达了系统执行什么功能, 谁使用它,以及哪些行为是强制性的,哪些是可选的.
6. 已展示的常见建模指南
该图体现了若干最佳实践在UML用例建模中的应用:
| 指南 | 如何应用 |
|---|---|
| 使用以目标为导向的用例名称 | 下订单, 跟踪订单, 应用促销代码——均以动词开头并描述用户目标。 |
| 保持图表可读 | 仅10 个用例已展示——适用于大多数业务领域(推荐数量为 5–12)。 |
| 将外部系统作为参与者 | PaymentGW被建模为参与者而非用例。正确分离了关注点。 |
| 使用注释消除歧义 | 注释说明PaymentGW是外部系统,且促销代码为可选——这对避免误解至关重要。 |
| 使用参与者泛化以减少杂乱 | `Customer < |
使用include和extend正确 |
明确区分强制行为与可选行为。 |
📌 警告:许多图表误用
<<extend>>来表示“可选”,却未理解扩展的条件性质。本图表避免了该错误。
7. 潜在改进与批评
虽然该图表表现良好,但以下建设性建议用于改进:
🔧 1. 添加构造型以增强清晰度
actor "Payment Processor" as PaymentGW <<system>>
- 原因: 明确表明这是一个外部系统,而非人类角色。
- 好处: 减少歧义,特别是在大型模型中。
🔧 2. 明确应用促销代码扩展条件
当前:
note bottom of (Apply Promo Code)
Optional – only when a valid code is entered
end note
- 更佳方案: 使用条件表示法或守卫在
<<extend>>箭头上:
- 为什么: 比注释更精确——直接将扩展与条件关联。
🔧 3. 考虑添加一个查看订单历史 用例
- 目前缺失,但对顾客和餐厅都可能很重要。
- 可作为
注册顾客用例。
🔧 4. 分组相关用例(可选)
对于较大的图表,将用例分组到包:
包 "订单管理" {
(下订单)
(跟踪订单)
(应用促销码)
}
包 "支付" {
(处理支付)
(使用钱包)
(卡支付)
(数字钱包支付)
}
- 好处: 提高可扩展性和可读性。
8. 下一步是什么?
本案例展示了如何结构良好的用例图清晰简洁地捕捉复杂的业务逻辑。为了加深您的理解,以下是建议的后续步骤:
🔄 选项 1:以餐厅为中心的视角
从餐厅的视角对同一领域进行建模:
- 聚焦于
管理菜单,接受/准备订单,查看订单,更新状态. - 显示
餐厅作为主要参与者。 - 包含
顾客作为次要参与者(例如,顾客发送订单 →餐厅接收订单)。
✅ 优势:揭示不同的系统目标和参与者角色。
🔄 选项 2:添加更多扩展点
增强下单 与:
应用优惠券(如果促销代码无效 →<<扩展>>带错误消息)请求特殊说明(可选)安排订单(用于未来配送)
🔄 选项 3:比较 包含 对比 扩展 带示例
| 用例 | <<包含>> |
<<扩展>> |
|---|---|---|
下单 → 处理支付 |
✅ 必填 | ❌ 非可选 |
下单 → 应用促销代码 |
❌ 非必填 | ✅ 条件性 |
登录 → 验证身份 |
✅ 始终需要 | ❌ 不适用 |
结账 → 应用折扣 |
✅ 始终 | ✅ 仅当存在折扣时 |
📌 经验法则:
- 使用
<<包含>>当行为 必须发生.- 使用
<<扩展>>当行为 可能发生 在特定条件下。
🔄 选项 4:转换为序列图或活动图
用于更深入的分析:
- 序列图: 显示
下订单→处理支付→交付订单包含参与者与系统之间的消息。 - 活动图: 对以下中的决策点进行建模
处理支付(例如:卡片被拒 → 重试或切换至电子钱包)。
9. 结论
本案例研究表明,一个精心设计的用例图远不止是一幅视觉草图——它是一个战略沟通工具,它能够:
- 明确系统范围,
- 捕捉业务规则,
- 指导开发工作,
- 避免误解。
该外卖配送平台的图示是一个强有力的范例,体现了:
- UML 符号的正确使用,
- 合理的建模决策,
- 清晰的关注点分离,
- 注释与泛化的有效运用。
通过遵循此处展示的原则——以目标为导向的命名, 以及正确的包含/扩展, 参与者泛化,和 策略性地使用注释 — 您可以创建既 准确 又 可操作.
✅ 最终要点
| 原则 | 此处是否适用? | 为何重要 |
|---|---|---|
| 使用以目标为导向的用例名称 | ✅ 是 | 提高清晰度并聚焦用户 |
| 保持图表规模可控 | ✅ 是(10 个用例) | 防止认知过载 |
| 将外部系统作为参与者 | ✅ 是 | 正确分离关注点 |
| 使用注释提供上下文 | ✅ 是 | 防止误解 |
| 使用泛化减少冗余 | ✅ 是 | 使图表具有可扩展性和可维护性 |
正确<<include>> 和 <<extend>> 方向 |
✅ 是 | 确保行为建模的准确性 |









