📄 一句话概括
状态机图只回答这个东西有哪些状态、什么事件让它换状态——实测订单 6 个状态、7 条迁移、0 个到不了的状态,它画的是同一个东西的一生。
📝 本节和前面几节的关系
8.12 的活动图画的是一件事的流程,这一节画一个东西的一生。两者最容易混,差别就在主语。
一、与活动图的区别
活动图的主语是【一件事】:报销这件事怎么走。 状态机图的主语是【一个东西】:这张订单现在是待审还是已批。 判据:能问出【它现在是什么状态】就用状态机,能问出【走到第几步】就用活动图。
二、实测:6 状态 7 迁移
状态:新建、待审、已批、已发、完成、已退——6 个。 迁移 7 条,事件 7 种(提交、通过、驳回、发货、签收、退货、退款)。 从【新建】出发可达 6 个状态,到不了的状态 0 个——这张图是连通的。
三、连通性检查
做法:从初始状态出发,顺着迁移一路走过去,走不到的节点就是孤岛。 孤岛一般意味着画漏了入口——某个状态其实只能由另一个没画出来的事件到达。 反过来也要查:有没有【进得去出不来】的状态(除终点外)。
四、两个常见错误
把动作当状态:写【正在审核】是状态,写【审核】是动作。 忘了终态:状态机可以没有绝对终点(【完成】还能退货),但必须能说出哪些是稳定停靠点。 注意【完成】既是终点又是起点——所以这张图里没有绝对的终态。
五、动手 Demo:使用状态机图表示状态的变化
用三元组列出订单的状态迁移:当前状态、事件、下一个状态。 再从初始状态出发做可达性遍历,找孤岛。
trans = [("新建", "提交", "待审"), ("待审", "通过", "已批"),
("待审", "驳回", "新建"), ("已批", "发货", "已发"),
("已发", "签收", "完成"), ("完成", "退货", "已退"),
("已退", "退款", "完成")]
states = []
for a, e, b in trans:
for s in (a, b):
if s not in states:
states.append(s)
reach = {states[0]}
for _ in range(len(states)):
for a, e, b in trans:
if a in reach:
reach.add(b)
print(len(states), len(trans), len(reach) - len(states)) # 6 7 0
实跑输出:
--------------------------------------------------------------------
使用状态机图表示状态的变化
--------------------------------------------------------------------
状态机图只回答:**这个东西有哪些状态、什么事件让它换状态。**实测:
当前状态 事件 下一个状态
---------------------------------
新建 提交 待审
待审 通过 已批
待审 驳回 新建
已批 发货 已发
已发 签收 完成
完成 退货 已退
已退 退款 完成
状态 6 个
迁移 7 条
事件种类 7 种
从【新建】出发能到 6 个
到不了的状态 0 个
**注意【完成】既是被到达的终点,又是退货的起点**——状态机里没有绝对的终点。
**到不了的状态为 0 个,说明这张图目前是【连通的】**;一旦加错一条边,就会冒出孤岛。
**这就是 8.13 那句【表示状态的变化】:它画的是【同一个东西】的一生,不是流程。**
实测:6 个状态、7 条迁移、7 种事件,从新建可达全部 6 个(孤岛 0 个)。 到不了的状态为 0 说明图是连通的;一旦加错一条边,立刻冒出孤岛。 【完成】既是终点又是退货的起点——所以它没有绝对的终态。
30 秒实验
- 给你系统里的一个核心对象列状态与事件,画成状态机图。
- 做一次可达性遍历,看看有没有进得去出不来的状态。
常见误区
- 把动作当状态。审核是动作,正在审核才是状态。
- 以为状态机必须有终态。【完成】还能退货,就没有绝对终点。
自测三问(点开对答案)
1. 状态机图和活动图怎么分? —— 主语不同:活动图画的是一件事的流程,状态机图画的是一个东西的一生。 2. 实测数字是多少? —— 6 个状态、7 条迁移、7 种事件,从新建可达全部状态,孤岛 0 个。 3. 为什么说要查连通性? —— 走不到的状态通常是画漏了入口;反过来也要查有没有进得去出不来的状态。- ☐ 8.14 弥补自然语言和计算机语言缺点的【语言】
相关笔记
- 使用活动图表示工作流程 — 相邻但不同的一对
- 使用用例图表示交给计算机的工作 — 第三类用法的入门
- 弥补自然语言和计算机语言缺点的【语言】 — 全章收口
- 🧩 面向对象是怎样工作的 · 索引