15 KiB
第5章 顺序图与协作图
考试重要度:★★★★
核心内容:顺序图的四个核心元素、六种消息类型、调用消息vs异步消息、顺序图与协作图的对比
📢 从打电话理解交互图
💬 你打电话给朋友借钱,整个对话过程是这样的:
你 → 拨号 → 朋友接电话 → 你说"借我500" → 朋友说"好" → 你挂电话
这就是一个交互过程——两个对象之间按时间顺序传递消息。在UML中,我们用顺序图和协作图来描述这个过程。
💡 一、顺序图的四个核心元素
┌─────────────────────────────────────────────┐
│ 对象 生命线 控制焦点(激活期) │
│ ┌───┐ │ ┌──┐ │
│ │obj│ │ │ │ │
│ └─┬─┘ │ └──┘ │
│ │- - - - - │- - - - - - - - - - - │
│ │ │ 消息→ │
│ │ │ ┌──┐ │
│ │ │ │ │ │
│ │ │ └──┘ │
└─────────────────────────────────────────────┘
| 元素 | 说明 | 画法 |
|---|---|---|
| 对象 | 类的实例,参与交互的实体 | 矩形,顶部放置 |
| 生命线 | 对象存在的时间线 | 从对象向下延伸的虚线 |
| 控制焦点(激活期) | 对象正在执行操作的时间段 | 生命线上的细长矩形条 |
| 消息 | 对象之间的一次通信 | 带箭头的直线 |
💡 二、消息的语法格式
消息的完整格式:
[前置条件] [警戒条件] [序号] [返回值:=] 消息名([参数列表])
例子:
2: display(x, y) → 简单消息,序号2
1.3.1: p := find(specs) → 嵌套消息,有返回值
[x<0] 4: invert(x, color) → 条件消息
3.1*: update() → 循环消息
消息序号的含义
1, 2, 3— 顺序发送的消息1.1, 1.2, 1.3— 消息1内部的嵌套调用(1.1必须在1完成之前完成)A1, B1— 并发线程中的消息
💡 三、六种消息类型
| 消息类型 | 说明 | 画法 |
|---|---|---|
| 调用消息 (同步) | 发送者等待接收者完成才继续 | 实线实心箭头 → |
| 异步消息 | 发送者不等待,继续执行 | 实线开放箭头 ⇢ |
| 返回消息 | 从调用返回 | 虚线开放箭头 ⇢ |
| 反身消息 | 发给自己 | 绕回自己的箭头 |
| 阻止消息 | 接收者不能立即接收就放弃 | 特殊标记 |
| 超时消息 | 等待指定时间,超时就放弃 | 特殊标记 |
📌 消息类型的画法速查
这一节把六种消息类型的实际画法用字符画的形式画出来,光看箭头符号记不住的话,照着画就行。
① 调用消息(同步)—— 实线 + 实心三角箭头
┌───┐ ┌───┐
│ A │ ──────────────────▶│ B │ ← 实线 + 实心三角
└───┘ └───┘
同步:等B做完再回来
② 异步消息 —— 实线 + 开放箭头(V形)
┌───┐ ┌───┐
│ A │ ─────────────────⇨ │ B │ ← 实线 + 开放箭头
└───┘ └───┘
异步:发完就接着干自己的事
③ 返回消息 —— 虚线 + 开放箭头
┌───┐ ┌───┐
│ A │ ◀─ ─ ─ ─ ─ ─ ─ ─ ─ │ B │ ← 虚线 + 开放箭头
└───┘ └───┘
返回值(可省略不画)
④ 反身消息 —— 自己绕回来
┌───┐
│ A │ ───┐
└───┘ │
│ │
◀─────┘
(即"对象调用自己的方法")
⑤ 阻止消息 —— 实线 + 叉 ✕
接收方当时忙,直接放弃这次调用。
┌───┐ ┌───┐
│ A │ ─────────────────╳ │ B │ ← 实线 + 叉
└───┘ └───┘
B没空,A立刻放弃不等
⑥ 超时消息 —— 实线 + 倒三角 ⏳
等待指定时间,超时就放弃。
┌───┐ ┌───┐
│ A │ ─────────────────⏳ │ B │ ← 实线 + 倒三角
└───┘ └───┘
等一段时间后超时
📌 完整顺序图示例
把所有消息类型都画在一张图里看效果:
客户 ATM界面 账户
┌───┐ ┌───┐ ┌───┐
│ │ │ │ │ │
╱│╲ │ ╱│╲ │ ╱│╲ │
╱ ╲ │ ╱ ╲ │ ╱ ╲ │
┌───┐ ┌───┐ ┌───┐
│ │ │ │ │ │
│ │ 1: 取款(500) │ │ │ │ ← ① 调用消息
│ ├──────────────▶│ │ │ │
│ │ │ │ 2: 查询余额() │ │ ← ① 调用消息
│ │ │ ├───────────────▶│ │
│ │ │ │ │ │
│ │ │ │ ◀─ 3: 余额 ─── │ │ ← ③ 返回消息
│ │ │ │ │ │
│ │ │ │ 4: 扣款(500) │ │ ← ① 调用消息
│ │ │ ├───────────────▶│ │
│ │ │ │ │ │
│ │ 5: 出钞 │ │ │ │ ← ② 异步消息
│ │◀─ ─ ─ ─ ─ ─ ─│ │ │ │
│ │ │ │ │ │
📌 组合片段(Combined Fragment)速查
当顺序图比较复杂时,可以用框选区域的方式来表达条件、循环、并行等逻辑。
┌────────────── alt: 余额判断 ──────────────┐
│ │
│ │ 条件A: │
│ │ 4.1: 扣款(amount) ──▶ │
│ │ │
├────────────────────────────────────────────┤
│ │
│ │ 条件B: │
│ │ 4.2: 显示"余额不足" ──▶ │
│ │
└────────────────────────────────────────────┘
常用组合片段关键字:
| 关键字 | 含义 | 用途 |
|---|---|---|
alt |
抉择(多选一) | 相当于 if-else |
opt |
可选(满足才执行) | 相当于单分支 if |
loop |
循环 | 相当于 for/while |
par |
并行 | 多个事件流同时进行 |
neg |
非法 | 描述不允许发生的场景 |
critical |
关键 | 必须原子执行的区域 |
📌 协作图(Communication Diagram)的画法
协作图 = 顺序图的"空间版"——没有生命线,但消息必须带完整序号。
1: 输入金额
客户 ──────────────▶ ATM界面
○ │
╱│╲ │ 2: 查询余额
╱ ╲ ▼
账户
╱│╲
╱ ╲
▲
│ 3: 返回余额
◀───── 4.1*: 出钞 ─────┘
(出钞多次循环)
协作图的关键特征:
- 对象之间的连线(关联)作为消息传递的路径
- 消息的前缀序号必须完整(
1,1.1,1.1.1) {new}标签表示对象在交互中被创建{destroy}标签表示对象在交互中被销毁
┌──────────┐ ┌──────────┐
│ :Order │ │ :Payment │
│{new} │ 1: 创建支付 │ │
└──────────┘ ────────────────▶ └──────────┘
│
│ {destroy}
▼
(被销毁)
🔑 一句话记忆口诀:实心三角是同步,开放箭头是异步;返回用虚线开放箭头,反身消息自己绕;alt/loop/par 框选区域,条件循环并行都能搞。
🔑 调用消息 vs 异步消息(必考!)
| 对比维度 | 调用消息 | 异步消息 |
|---|---|---|
| 发送者行为 | 发出后停下来等 | 发出后继续干活 |
| 控制焦点 | 发送者出现等待(重叠矩形条) | 发送者不等待 |
| 典型场景 | 查询数据库(必须等结果) | 写日志文件(可以后台进行) |
| 返回消息 | 必有返回,可以省略不画 | 如果是过程调用必有返回 |
💬 比喻:
- 调用消息像打电话——你说一句,等对方回一句。
- 异步消息像发微信——你发一条,继续干自己的事,对方看到再回。
💡 四、顺序图的两种形式
| 形式 | 说明 |
|---|---|
| 一般形式 | 包含条件、分支、循环,描述所有可能的场景 |
| 实例形式 | 只有一个具体的场景,没有任何分支和循环 |
💬 例:取款的一般形式包含"余额够"和"余额不够"两个分支;而某次具体取款(余额够)就是实例形式。
条件消息和循环消息的表达
两种方法:
- 在消息上直接标注:
[x>0] 3: doSomething()或2.1*: update() - 使用交互架构(框选一个区域,标注
loop或alt)
💡 五、协作图
协作图 vs 顺序图
| 维度 | 顺序图 | 协作图 |
|---|---|---|
| 强调 | 时间顺序 | 空间位置关系 |
| 生命线 | 有(从上到下) | 无 |
| 控制焦点 | 有(矩形条) | 无 |
| 消息序号 | 通常简化 | 必须完整标注 |
| 多对象 | 不直观 | 可以表达 |
| 主动对象 | 不直观 | 可以表达 |
🔑 核心区别:顺序图强调"什么时间谁调用了谁",协作图强调"谁跟谁有连接关系"。
协作图的特殊元素
| 元素 | 说明 |
|---|---|
| 多对象 | 代表一组对象,发给它的消息是发给整个集合 |
| 主动对象 | 拥有自己控制线程的对象,可以主动发起消息 |
| {new} | 标记对象在交互中被创建 |
| {destroy} | 标记对象在交互中被销毁 |
✍️ 边学边练(一)
题目:ATM取款的基本流程如下,请画出分析阶段的顺序图。
- 用户输入取款金额
- 系统判断账户余额是否足额
- 若足额,则出钞并修改账户余额
- 若不足额,则取款失败
答案:
顺序图包含对象::客户、:ATM界面、:账户
消息序列:
1. 客户 → ATM界面: 输入金额(amount)
2. ATM界面 → 账户: 查询余额()
3. 账户 → ATM界面: 返回余额(balance)
4. ATM界面 → 自己: [balance>=amount]判断
5a. ATM界面 → 账户: 扣款(amount) [金额足够]
5b. ATM界面 → 客户: 显示"余额不足" [金额不足]
⚠️ 关键:步骤4的判断是ATM界面对象自己的处理,用反身消息或不画都可以。
✍️ 边学边练(二)
题目:判断以下场景应该用调用消息还是异步消息。
- 用户点击"登录"按钮,系统验证用户名密码
- 用户上传文件后,系统后台写入日志
- 用户查询订单列表,系统返回查询结果
- 系统给所有订阅用户发送邮件通知
答案:
- 调用消息(同步)—— 必须等验证结果,用户才能进入下一步
- 异步消息—— 写日志不阻塞用户操作
- 调用消息(同步)—— 必须等返回结果才能显示
- 异步消息—— 发邮件是批量后台操作,不需要等待
🔑 判断标准:发送者是否必须等待结果才能继续。必须等=调用消息,不必等=异步消息。
💡 六、交互建模的步骤
- 根据一个用例的用例描述,找出基本事件流和可选事件流
- 确定参与交互的对象(参考类图)
- 按事件流的先后次序确定消息发送次序
- 标注需要创建和撤销的对象
- 处理循环和分支消息
📝 章末自测
1. 填空题
- 顺序图的四个核心元素是:( ____ )、( ____ )、( ____ )、( ___ _ )
- 发送后等待返回的消息叫( ____ )消息,发送后继续执行的消息叫( ____ )消息
- 顺序图强调( _____ )顺序,协作图强调( ____ )关系
2. 判断题
- ( ) 调用消息的返回消息必须画出来
- ( ) 顺序图可以表示对象的创建和销毁
- ( ) 协作图中消息序号1.1表示它在消息1完成后才开始
3. 简答题
- 顺序图和协作图各有什么优势和适用场景?
答案: 填空题:对象、生命线、控制焦点、消息;调用(同步)、异步;时间、空间位置
判断题:
- ❌ 调用消息的返回消息可以省略不画(隐式)
- ✅ 对象顶部放置={new},虚线末端×={destroy}
- ❌ 消息1.1在消息1完成之前就必须完成(嵌套含义)
简答题:
- 顺序图:适合展示按时间顺序发生的消息交互,直观易懂,适合分析单个用例的执行流程
- 协作图:适合展示对象之间的静态连接关系,能表达多对象和并发,适合整体架构分析
🔗 上一篇:第4章 类图与对象图 | 下一篇:第6章 状态图与活动图