1. 用例图基础入门
第一次接触UML用例图时,我完全被那些小人图标和椭圆搞懵了。直到参与了一个电商项目,才真正理解它的价值。用例图就像系统的"用户手册"草图,用最直观的方式告诉我们:谁会用这个系统?能用它做什么?
核心三要素其实特别简单:
- 参与者(Actor):就是系统外部的使用者,比如顾客、管理员。画图时用火柴人表示,我常开玩笑说这是"系统门口的保安"——决定谁能进谁不能进
- 用例(Use Case):系统提供的具体功能,比如"下单"、"支付"。用椭圆表示,我喜欢把它想象成系统里的"功能房间"
- 系统边界:一个矩形框,把属于系统的用例框起来,就像给系统画了个"地盘"
新手最容易犯的错是把系统内部流程画进用例图。记得有次评审,同事把"验证库存"这种内部操作也画成用例,结果被产品经理当场吐槽:"用户才不关心你怎么验证库存,他们只关心能不能买到东西!"
2. 实战:在线书店用例建模
去年给朋友的书店做系统改造,我们用Miro白板边讨论边画图,整个过程就像玩拼图游戏:
2.1 识别参与者
- 基础用户(未登录访客)
- 注册会员
- 图书管理员
- 支付网关(外部系统)
这里有个技巧:用"XX能否独立完成目标"来检验参与者。比如"支付"需要支付网关参与,但"浏览图书"不需要。
2.2 定义用例
我们通过用户访谈整理了这些核心用例:
- 浏览图书目录
- 搜索图书
- 加入购物车
- 创建订单
- 在线支付
- 管理库存(管理员专属)
每个用例都用"动词+名词"格式命名,避免出现"用户进行xx操作"这种冗长描述。
2.3 绘制初版草图
[系统边界] ┌───────────────────────┐ │ 浏览图书目录 │ │ 搜索图书 │ │ 加入购物车 │ │ 创建订单 │ │ 在线支付 │ └───────────┬───────────┘ │ 基础用户────┘ 支付网关 注册会员────┐ │ ├───────┤ 图书管理员─┘ │ │ [支付网关]3. 四种关系的深度解析
刚开始学用例关系时,我总混淆包含和扩展。直到导师用点餐场景比喻:
- 包含关系像套餐里的固定搭配(点汉堡必须配薯条)
- 扩展关系像可选的加料(汉堡可以额外加芝士)
3.1 关联关系
最简单的连线,表示"谁能用这个功能"。在图书系统中:
- 会员关联"创建订单"
- 管理员关联"管理库存"
3.2 泛化关系
发现会员分普通/VIP两种,VIP有"使用优惠券"特权。用泛化表示继承:
会员 / \ 普通会员 VIP会员 | 使用优惠券3.3 包含关系
把"创建订单"拆解发现必须经过"验证库存"和"计算运费",于是:
创建订单 →《include》→ 验证库存 创建订单 →《include》→ 计算运费3.4 扩展关系
支付时可能触发"使用积分抵扣",但不是每次都必须:
使用积分抵扣 →《extend》→ 在线支付4. 常见陷阱与解决方案
4.1 用例粒度过细
有同事把"输入验证码"也画成独立用例。正确做法是:
- 粗粒度用例:"用户注册"
- 细节留到用例规约文档中描述
4.2 混淆系统内外
把"发送短信通知"画在系统内。实际上:
- 用例应是"接收订单通知"(用户视角)
- 短信发送是内部实现细节
4.3 关系滥用
过度使用扩展关系会使图面混乱。经验法则是:
- 包含关系:必须执行的子流程
- 扩展关系:可选场景(频率<30%)
5. 工具技巧与团队协作
用过Visio、StarUML后,最终团队选择了PlantUML,因为:
- 代码化建模,方便版本控制
- 实时协作修改
- 自动生成文档
我们建立的协作流程:
- 产品经理写初步用例描述
- 架构师用PlantUML代码画图
- 开发团队通过Git提交修改建议
- 每周评审会上用投影仪集体优化
@startuml left to right direction actor 顾客 as C actor 管理员 as A rectangle 在线书店 { C --> (浏览图书) C --> (搜索图书) C --> (下单) (下单) .> (验证库存) : <<include>> (下单) .> (计算运费) : <<include>> A --> (管理库存) } @enduml6. 从用例图到需求文档
好的用例图应该能直接转化为需求规格说明书。我们的模板包含:
- 用例名称:创建订单
- 参与者:注册会员
- 前置条件:用户已登录,购物车非空
- 基本流程:
- 系统验证库存
- 系统计算运费
- 显示订单确认页
- 备选流程:
- A1.库存不足时提示替换方案
- 业务规则:
- 单笔订单最多10件商品
- 非功能需求:
- 响应时间<2秒
这种结构化表达让开发测试都有据可依,减少后续沟通成本。