知识卡片

状态图的三种实现方式对比

结构图卡 · 1949.j

内容

状态图落地到代码主要有三种方式,各有取舍:嵌套switch语句最直接,但哪怕状态不多也很快变成又长又乱、容易失控的代码,作者即使在简单情况下也不喜欢用;状态模式(state pattern)给每个状态建一个子类,顶层抽象类把所有事件处理方法默认实现为什么都不做,具体状态类只需覆盖自己真正响应的事件,组织清晰、每种情况代码量小,但需要为每个状态多建一个类;状态表(state table)把状态图信息表达为纯数据,再配一个解释器或代码生成器去消费这份数据,前期建造成本更高,但建好后可以复用、甚至能在不重新编译的情况下动态修改。三种方式本质上都会产出相当公式化的代码,更好的做法通常是用代码生成来完成,而不是手写。

结构图:

flowchart TD
    A[状态图] --> B[嵌套switch: 直接但易失控, 不推荐]
    A --> C[状态模式: 每状态一个子类, 组织清晰, 需多建类]
    A --> D[状态表: 数据驱动, 前期成本高, 可复用/可动态修改]
    B & C & D --> E[代码都相当公式化 -> 更适合用代码生成而非手写]

参考来源

- 位置:《UML精粹:标准对象建模语言简明指南(第3版)》第10章《状态机图》(源文件:_epub-src/EPUB/9.xhtml) - 结论依据:原文逐一评价三种方式:"处理状态图最直接的方法是嵌套switch语句……即使是简单的情况我也不喜欢使用它""状态模式创建状态类层次来处理状态的行为……层次的顶层是一个抽象类,它将所有事件处理方法实现为什么都不做""状态表方法捕获状态图信息为数据……运行时状态表也可以在无须重新编译的情况下修改"。 - 原始内容:状态图的实现主要有3种方式:嵌套switch、状态模式和状态表……即使是简单的情况我也不喜欢使用它……状态模式[Gang of Four]创建状态类层次来处理状态的行为……状态表(state table)方法捕获状态图信息为数据……显然,状态表一次要做比较多的工作,但是之后每一次有状态问题时都可以使用。