🧩 第八章 UML:查看无形软件的工具
📄 一句话概括

状态机图只回答这个东西有哪些状态、什么事件让它换状态——实测订单 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. 做一次可达性遍历,看看有没有进得去出不来的状态。

常见误区

  1. 把动作当状态。审核是动作,正在审核才是状态。
  2. 以为状态机必须有终态。【完成】还能退货,就没有绝对终点。
自测三问(点开对答案) 1. 状态机图和活动图怎么分? —— 主语不同:活动图画的是一件事的流程,状态机图画的是一个东西的一生。 2. 实测数字是多少? —— 6 个状态、7 条迁移、7 种事件,从新建可达全部状态,孤岛 0 个。 3. 为什么说要查连通性? —— 走不到的状态通常是画漏了入口;反过来也要查有没有进得去出不来的状态。

相关笔记