8.5 KiB
第6章 状态图与活动图
考试重要度:★★★★★
核心内容:状态图的组成(状态/转移/事件)、四种事件类型、活动图元素(泳道/分支/分叉汇合)、状态vs活动的区别
📢 从手机理解状态图和活动图
💬 你的手机有以下状态:闲置 → 解锁 → 使用中 → 锁屏 → 闲置。
每个状态之间的切换需要事件触发:点击屏幕、输入密码、按电源键……
这就是状态图——描述一个对象在生命周期内的状态变化。
而活动图描述的是一个流程:比如"打电话"这个活动——打开拨号盘 → 输入号码 → 点击拨号 → 通话 → 挂断。这其中可能涉及多个对象。
💡 一、状态图的核心元素
状态图三要素
┌──────────┐ 事件[条件]/动作 ┌──────────┐
│ 状态A │ ─────────────────→ │ 状态B │
└──────────┘ └──────────┘
| 要素 | 说明 |
|---|---|
| 状态 | 对象在某个时刻所处的条件或状况 |
| 转移 | 从一个状态到另一个状态的变化 |
| 事件 | 触发状态转移的原因 |
状态的组成
┌────────────────────────┐
│ 状态名 │
├────────────────────────┤
│ entry / 入口动作 │
│ exit / 出口动作 │
│ do / 持续活动 │
│ 内部转移(不离开状态) │
└────────────────────────┘
组合状态和历史状态
💬 组合状态:一个大状态里面还有小状态的变化过程。
例:汽车"行驶"状态里面还有子状态:加速、匀速、减速。
💬 历史状态:记住离开组合状态时处于哪个子状态,回来后可以接着来。
例:数据备份——中途被打断,恢复后可以继续从断点备份。
💡 二、四种事件类型
| 事件类型 | 含义 | 举例 |
|---|---|---|
| 调用事件 | 一个方法的调用 | 借书() → 借书证从"可借"变为"不可借" |
| 信号事件 | 一个异步发送的信号实体 | 遥控器发出"Play"信号 → CD机进入"播放"状态 |
| 变化事件 | 布尔表达式值发生变化 | 温度>100℃ → 锅炉进入"报警"状态 |
| 时间事件 | 到达某个时间点或时间段 | 30秒超时 → 从"拨号"回到"就绪" |
🔑 调用事件 vs 信号事件
| 对比 | 调用事件 | 信号事件 |
|---|---|---|
| 本质 | 调用一个方法 | 发送一个信号对象 |
| 发送方 | 可以是自己或其他对象 | 只能是其他对象 |
| 特点 | 可扩展性弱 | 信号类可泛化,扩展性强 |
💬 例:CD唱机——如果各种遥控信号作为遥控器的属性(变化事件),增加新信号就要修改遥控器类。如果把遥控信号建模为信号类(信号事件),增加新信号只需新增子类,不用改遥控器。
✍️ 边学边练(一)
题目:画出"图书"对象的状态图。
需求:新书购买后需编码才能入库。入库后可借出。借出的书不能被再借出。还书后可再借出。图书破损或过时必须下架,下架后不能再借出。
答案: 状态:未编码 → 可借(在库) → 已借出 → 可借(在库) → 已下架
转移:
- 未编码 → 可借:
编码() - 可借 → 已借出:
借出() - 已借出 → 可借:
还书() - 可借 → 已下架:
下架()[破损或过时] - 已借出 → 已下架:
下架()[破损或过时]
⚠️ 注意:状态图中有两个状态必须有"下架"转移(从可借和已借出都可以下架)。
💡 三、活动图的核心元素
活动图的基本元素
| 元素 | 说明 | 画法 |
|---|---|---|
| 活动 | 一个执行步骤 | 圆角矩形 |
| 起点 | 流程的开始 | 实心圆 ● |
| 终点 | 流程的结束 | 圆圈加实心圆 ⊙ |
| 分支 | 根据条件选择路径 | 菱形 ◇ |
| 分叉/汇合 | 并发执行的开始/结束 | 粗横线 |
| 泳道 | 标明活动由谁负责 | 纵向分区 |
| 对象流 | 活动之间传递的对象 | 带箭头的虚线 |
🔑 状态 vs 活动(必考区别!)
| 对比 | 状态 | 活动 |
|---|---|---|
| 本质 | 对象所处的境况 | 一段程序代码的执行过程 |
| 持续时间 | 可以很长(等待状态) | 相对短暂(执行完就结束) |
| 关系 | 是活动执行后的结果 | 是导致状态变化的原因 |
| 关注对象 | 一个对象 | 可以涉及多个对象 |
| UML图 | 状态图 | 活动图 |
💬 比喻:做菜的过程(洗菜→切菜→炒菜→装盘)是活动;菜做完了变成"已做好"是状态。
活动图的两种用途
- 对业务流程建模(不带泳道)—— 用于需求分析,描述用例的工作流程
- 对系统操作建模(带泳道)—— 用于系统设计,把步骤落实到具体对象
✍️ 边学边练(二)
题目:画出"借书"用例的带泳道活动图。
流程:图书管理员录入图书条码和借书证号 → 系统判断借书证能否借书 → 若不能,显示原因并结束 → 若能,生成借阅记录,修改可借本数。
答案: 泳道划分:图书管理员 | 系统
图书管理员泳道:
录入条码和借书证号 →
系统泳道:
判断能否借书 → [不能] → 显示原因 → 结束
→ [能] → 生成借阅记录 → 修改可借本数 → 结束
⚠️ 关键:分叉用菱形,两个分支最终汇合到结束。
💡 四、状态/活动与用例/方法的关系
状态与方法、用例的联系
- 一个方法的执行 → 属性值改变 → 对象进入新状态
- 对象处于不同状态 → 影响后续哪些用例可以执行
- 一个对象完整的状态图 = 多个用例的顺序图融合
活动与方法、用例的联系
- 一个活动 = 一个方法中的部分(或全部)语句执行
- 一个方法可能需要多个活动来完成
- 一个用例 = 若干个活动,通常一个用例对应一个活动图
✍️ 边学边练(三)
题目:借书证的状态图中有"可借书"和"不可借书"状态。问:
- "借书"操作对应什么事件类型?
- 从"不可借书"转回"可借书"需要什么事件?
- "借书证"的状态图与哪些用例有关?
答案:
- 调用事件——"借书"本质上是对借书证对象调用借书方法
- 还书事件——读者还书后,借书证的可借本数减1,重新变为可借
- 与"借书""还书""挂失借书证"等用例有关。这些用例的顺序图融合起来,就构成了借书证的完整状态图
📝 章末自测
1. 填空题
- 状态图描述的是( ___ )( ___ )个对象的状态变化
- 四种事件类型是:调用事件、( ___ )( ___ )、( ___ )( ___ )、时间事件
- 活动图中的菱形表示( ___ )( ___ ),粗横线表示( ___ )( ___ )
2. 判断题
- ( ) 状态图和活动图都可以描述多个对象的交互
- ( ) 信号事件比调用事件更易于扩展
- ( ) 一个活动可能跨越多个泳道
- ( ) 带泳道的活动图用在系统设计阶段
3. 简答题
- 简述状态和活动的区别。
- 什么情况下应该用状态图,什么情况下应该用活动图?
答案: 填空题:一(单个);信号事件、变化事件;分支、分叉/汇合
判断题:
- ❌ 状态图只描述一个对象
- ✅ 信号类可继承扩展
- ❌ 每个活动只属于一个泳道
- ✅ 带泳道用于设计阶段
简答题:
- 状态是对象的境况(活动执行后的结果),可以持续很长时间;活动是代码的执行过程,相对短暂。状态变化由活动引起。
- 状态图:描述一个对象生命周期内的状态变迁(如订单状态、借书证状态)。活动图:描述一个业务流程或算法步骤(如取款流程、登录验证流程)。
🔗 上一篇:第5章 顺序图与协作图 | 下一篇:第7章 组件图与部署图