🌪 一、一个被反复踩坑的真实问题:业务状态越加越乱
在绝大多数后端项目里,你一定见过这样的状态定义:
0 - 待处理
1 - 审核中
2 - 审核通过
3 - 审核拒绝
4 - 已撤回
5 - 系统关闭
6 - 超时关闭
7 - 重新提交
8 - 待复核
…
随着业务扩大,状态从 5 个 → 20 个 → 40 个。
更恐怖的是:
- 某些状态之间能跳转
- 某些不能
- 某些需要回滚
- 某些需要触发子流程
- 某些状态无法复现
- 某些逻辑在半年后没人知道为什么这么写
最终业务代码变成:
if (state == 3 && type == 7 && userRole != ADMIN && ...) {
// 十几行逻辑
}
这种代码:
无法维护、无法扩展、无法审计、无法调试。
🧊 二、没有状态机,业务一定混乱
复杂业务为什么失控?
因为它符合三个条件:
1)状态多(状态爆炸)
订单、审批、项目管理、工单……
都有 20+ 状态。
2)行为多(行为导致转移复杂)
例如订单:
- 取消订单
- 修改订单
- 自动关闭
- 系统补偿
- 审核拒绝
- 用户投诉
- 发货失败
- 退款发起
- 补差价
…
每个行为可能改变状态,也可能不改变。
3)业务例外多(边界逻辑)
例如:
- 处于某状态时用户不能操作
- 管理员可以越过某状态
- 退款中不能取消订单
- 自动关闭只允许未支付状态
导致规则 100+ 条。
当状态 × 行为 × 例外 相乘后,就是:
业务爆炸的根源。
🧠 三、状态机(State Machine)是解决复杂业务的唯一可持续方案
状态机提供三种能力:
1)状态转移矩阵(State Transition Matrix)
定义每种状态允许转到哪些状态:
| 当前状态 | 行为 | 下一个状态 |
|---|---|---|
| 待审核 | 审核通过 | 已通过 |
| 待审核 | 审核拒绝 | 已拒绝 |
| 已拒绝 | 重新提交 | 待审核 |
这是业务清晰化的核心。
2)行为驱动(Action-Driven)
行为不再是“直接写业务逻辑”,而是:
Action → 验证 → 状态机判断 → 执行业务 → 转状态 → 触发副作用
让业务收敛到一个流程模板。
3)副作用控制(Side Effects Control)
副作用如:
- 发消息
- 写日志
- 推送通知
- 创建子流程
- 调用下游 API
全部绑定到状态转换上,逻辑清晰又可观察。
🧱 四、状态机带来的五大工程价值
1)避免状态混乱
所有转移路径可视化:
待审核 → 已批准 → 归档
待审核 → 已拒绝 → 重新提交 → 待审核
2)避免重复执行(天然幂等)
你不能从“已拒绝”直接跳到“已归档”。
状态机帮你阻断了非法调用。
3)避免业务扩展困难
新增状态,只需新增节点与链接。
4)避免逻辑散落
所有状态管理集中在一个模块。
5)支持“埋点、审计、回溯、监控”
业务过程变成链路,可回放、可记录。
🛠 五、构建企业级状态机的通用架构
工程落地一般如下:
Action → StateMachine.validate()
→ Transition
→ DomainService
→ EventEmitter
→ Projection(可选)
状态机模块职责:
- 校验
- 状态转换
- 副作用触发
- 转换记录(用于审计)
📘 六、案例:某审批系统使用状态机后带来的改变
之前的代码:
- 四处 if 状态判断
- 审批人更新失败时直接卡住流程
- 边界逻辑没人敢改
- “重新申请”逻辑特别复杂
- 大量线上 BUG
引入状态机后:
- 审批逻辑全图形化
- 状态转移表自动生成文档
- 研发和产品讨论基于“状态图”而不是“脑补”
- 新增“驳回到任意节点”,“会签模式”等功能轻松可扩展
- BUG 数量减少 60%+
🎬 七、结语
状态机不是“设计模式”,它是:
复杂业务的生命线。
所有大型系统都应该有一个状态机体系。
否则业务最终一定失控。