224 lines
8.3 KiB
Markdown
224 lines
8.3 KiB
Markdown
|
|
# 第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` — 并发线程中的消息
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 💡 三、六种消息类型
|
|||
|
|
|
|||
|
|
| 消息类型 | 说明 | 画法 |
|
|||
|
|
|----------|------|------|
|
|||
|
|
| **调用消息** (同步) | 发送者等待接收者完成才继续 | 实线实心箭头 → |
|
|||
|
|
| **异步消息** | 发送者不等待,继续执行 | 实线开放箭头 ⇢ |
|
|||
|
|
| **返回消息** | 从调用返回 | 虚线开放箭头 ⇢ |
|
|||
|
|
| **反身消息** | 发给自己 | 绕回自己的箭头 |
|
|||
|
|
| **阻止消息** | 接收者不能立即接收就放弃 | 特殊标记 |
|
|||
|
|
| **超时消息** | 等待指定时间,超时就放弃 | 特殊标记 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔑 调用消息 vs 异步消息(必考!)
|
|||
|
|
|
|||
|
|
| 对比维度 | 调用消息 | 异步消息 |
|
|||
|
|
|----------|----------|----------|
|
|||
|
|
| **发送者行为** | 发出后**停下来等** | 发出后**继续干活** |
|
|||
|
|
| **控制焦点** | 发送者出现等待(重叠矩形条) | 发送者不等待 |
|
|||
|
|
| **典型场景** | 查询数据库(必须等结果) | 写日志文件(可以后台进行) |
|
|||
|
|
| **返回消息** | 必有返回,可以省略不画 | 如果是过程调用必有返回 |
|
|||
|
|
|
|||
|
|
💬 **比喻**:
|
|||
|
|
- 调用消息像**打电话**——你说一句,等对方回一句。
|
|||
|
|
- 异步消息像**发微信**——你发一条,继续干自己的事,对方看到再回。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 💡 四、顺序图的两种形式
|
|||
|
|
|
|||
|
|
| 形式 | 说明 |
|
|||
|
|
|------|------|
|
|||
|
|
| **一般形式** | 包含条件、分支、循环,描述所有可能的场景 |
|
|||
|
|
| **实例形式** | 只有一个具体的场景,没有任何分支和循环 |
|
|||
|
|
|
|||
|
|
💬 例:取款的一般形式包含"余额够"和"余额不够"两个分支;而某次具体取款(余额够)就是实例形式。
|
|||
|
|
|
|||
|
|
### 条件消息和循环消息的表达
|
|||
|
|
|
|||
|
|
**两种方法**:
|
|||
|
|
1. 在消息上直接标注:`[x>0] 3: doSomething()` 或 `2.1*: update()`
|
|||
|
|
2. 使用交互架构(框选一个区域,标注`loop`或`alt`)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 💡 五、协作图
|
|||
|
|
|
|||
|
|
### 协作图 vs 顺序图
|
|||
|
|
|
|||
|
|
| 维度 | 顺序图 | 协作图 |
|
|||
|
|
|------|--------|--------|
|
|||
|
|
| **强调** | **时间顺序** | **空间位置关系** |
|
|||
|
|
| **生命线** | 有(从上到下) | 无 |
|
|||
|
|
| **控制焦点** | 有(矩形条) | 无 |
|
|||
|
|
| **消息序号** | 通常简化 | 必须完整标注 |
|
|||
|
|
| **多对象** | 不直观 | 可以表达 |
|
|||
|
|
| **主动对象** | 不直观 | 可以表达 |
|
|||
|
|
|
|||
|
|
🔑 **核心区别**:顺序图强调"什么时间谁调用了谁",协作图强调"谁跟谁有连接关系"。
|
|||
|
|
|
|||
|
|
### 协作图的特殊元素
|
|||
|
|
|
|||
|
|
| 元素 | 说明 |
|
|||
|
|
|------|------|
|
|||
|
|
| **多对象** | 代表一组对象,发给它的消息是发给整个集合 |
|
|||
|
|
| **主动对象** | 拥有自己控制线程的对象,可以主动发起消息 |
|
|||
|
|
| **{new}** | 标记对象在交互中被创建 |
|
|||
|
|
| **{destroy}** | 标记对象在交互中被销毁 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## ✍️ 边学边练(一)
|
|||
|
|
|
|||
|
|
**题目**:ATM取款的基本流程如下,请画出分析阶段的顺序图。
|
|||
|
|
|
|||
|
|
1. 用户输入取款金额
|
|||
|
|
2. 系统判断账户余额是否足额
|
|||
|
|
3. 若足额,则出钞并修改账户余额
|
|||
|
|
4. 若不足额,则取款失败
|
|||
|
|
|
|||
|
|
**答案:**
|
|||
|
|
顺序图包含对象:`:客户`、`:ATM界面`、`:账户`
|
|||
|
|
|
|||
|
|
消息序列:
|
|||
|
|
```
|
|||
|
|
1. 客户 → ATM界面: 输入金额(amount)
|
|||
|
|
2. ATM界面 → 账户: 查询余额()
|
|||
|
|
3. 账户 → ATM界面: 返回余额(balance)
|
|||
|
|
4. ATM界面 → 自己: [balance>=amount]判断
|
|||
|
|
5a. ATM界面 → 账户: 扣款(amount) [金额足够]
|
|||
|
|
5b. ATM界面 → 客户: 显示"余额不足" [金额不足]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
⚠️ 关键:步骤4的判断是ATM界面对象自己的处理,用反身消息或不画都可以。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## ✍️ 边学边练(二)
|
|||
|
|
|
|||
|
|
**题目**:判断以下场景应该用调用消息还是异步消息。
|
|||
|
|
|
|||
|
|
1. 用户点击"登录"按钮,系统验证用户名密码
|
|||
|
|
2. 用户上传文件后,系统后台写入日志
|
|||
|
|
3. 用户查询订单列表,系统返回查询结果
|
|||
|
|
4. 系统给所有订阅用户发送邮件通知
|
|||
|
|
|
|||
|
|
**答案:**
|
|||
|
|
1. **调用消息(同步)**—— 必须等验证结果,用户才能进入下一步
|
|||
|
|
2. **异步消息**—— 写日志不阻塞用户操作
|
|||
|
|
3. **调用消息(同步)**—— 必须等返回结果才能显示
|
|||
|
|
4. **异步消息**—— 发邮件是批量后台操作,不需要等待
|
|||
|
|
|
|||
|
|
🔑 **判断标准**:发送者是否**必须等待**结果才能继续。必须等=调用消息,不必等=异步消息。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 💡 六、交互建模的步骤
|
|||
|
|
|
|||
|
|
1. 根据一个用例的用例描述,找出**基本事件流**和**可选事件流**
|
|||
|
|
2. 确定参与交互的**对象**(参考类图)
|
|||
|
|
3. 按事件流的**先后次序**确定消息发送次序
|
|||
|
|
4. 标注需要**创建**和**撤销**的对象
|
|||
|
|
5. 处理**循环**和**分支**消息
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📝 章末自测
|
|||
|
|
|
|||
|
|
**1. 填空题**
|
|||
|
|
- 顺序图的四个核心元素是:( ___ )( ___ )、( ___ )( ___ )、( ___ )( ___ )、( ___ )( ___ )
|
|||
|
|
- 发送后等待返回的消息叫( ___ )( ___ )消息,发送后继续执行的消息叫( ___ )( ___ )消息
|
|||
|
|
- 顺序图强调( ___ )( ___ )顺序,协作图强调( ___ )( ___ )关系
|
|||
|
|
|
|||
|
|
**2. 判断题**
|
|||
|
|
- ( ) 调用消息的返回消息必须画出来
|
|||
|
|
- ( ) 顺序图可以表示对象的创建和销毁
|
|||
|
|
- ( ) 协作图中消息序号1.1表示它在消息1完成后才开始
|
|||
|
|
|
|||
|
|
**3. 简答题**
|
|||
|
|
- 顺序图和协作图各有什么优势和适用场景?
|
|||
|
|
|
|||
|
|
**答案:**
|
|||
|
|
**填空题**:对象、生命线、控制焦点、消息;调用(同步)、异步;时间、空间位置
|
|||
|
|
|
|||
|
|
**判断题**:
|
|||
|
|
- ❌ 调用消息的返回消息可以省略不画(隐式)
|
|||
|
|
- ✅ 对象顶部放置={new},虚线末端×={destroy}
|
|||
|
|
- ❌ 消息1.1在消息1**完成之前**就必须完成(嵌套含义)
|
|||
|
|
|
|||
|
|
**简答题**:
|
|||
|
|
- 顺序图:适合展示按时间顺序发生的消息交互,直观易懂,适合分析单个用例的执行流程
|
|||
|
|
- 协作图:适合展示对象之间的静态连接关系,能表达多对象和并发,适合整体架构分析
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
> 🔗 上一篇:[第4章 类图与对象图](第04章-类图与对象图.md) | 下一篇:[第6章 状态图与活动图](第06章-状态图与活动图.md)
|