复杂业务为什么一定要用状态机?一文讲透业务行为、状态爆炸、流程分歧的终极解决方案

44 阅读3分钟

🌪 一、一个被反复踩坑的真实问题:业务状态越加越乱

在绝大多数后端项目里,你一定见过这样的状态定义:

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%+

🎬 七、结语

状态机不是“设计模式”,它是:

复杂业务的生命线。
所有大型系统都应该有一个状态机体系。

否则业务最终一定失控。