java中用状态机模式管理业务生命周期,核心是将状态与流转规则从主逻辑剥离,通过状态类封装行为、抽象类统一机制、事件驱动替代硬编码,并确保状态变更原子化与一致性。

在 Java 中用状态机模式管理复杂业务生命周期,核心是把“状态”和“流转规则”从主业务逻辑中剥离出来,让每个状态的行为、转换条件、后续动作都集中定义、独立维护。这不是加个枚举再套 if-else,而是通过结构化设计实现可读、可测、可扩展的流程控制。
用状态类封装行为,订单不判断自己能不能发货
把每个业务状态(如待支付、已支付、已发货)做成独立类,统一实现接口(如 OrderState)。订单对象(Order)只持有一个状态引用,所有操作都委托给当前状态处理:
- 调用 order.pay() 时,实际执行的是 currentState.handlePay(order)
- 待支付状态收到 pay(),校验成功后主动调用 order.changeState(new PaidState())
- 已发货状态收到 pay(),直接抛异常或忽略——它知道自己不该响应这个动作
抽象类统一状态管理机制,子类专注业务差异
定义一个抽象订单类(AbstractOrder),封装共性能力:
- 持有 protected State currentState,提供受保护的 changeState() 方法
- 定义模板方法(pay()、ship()、cancel()),只做基础校验和委托,不写具体判断逻辑
- 构造时强制设置初始状态(如 changeState(new CreatedState())),避免空状态
- 子类(如 VipOrder)只需覆盖钩子方法(onShipped())添加短信通知等专属逻辑,不参与状态决策
用事件驱动替代硬编码分支,支持动态审批流
对于审批、工单等强流程场景,推荐基于事件的状态机(如 Spring StateMachine 或 Solon StateMachine):
- 定义清晰的事件枚举(PAY_ORDER、APPROVE、REJECT、RECALL)
- 配置状态转换规则:从 WAITING_PAYMENT 收到 PAY_ORDER → 进入 PAID
- 支持条件表达式:金额 > 100000 时,APPROVE 触发跳转至总经理节点;否则走部门经理节点
- 内置并行、会签、回退等语义支持,不用手动写线程同步或状态锁
避免常见陷阱:状态一致性与并发安全
状态机不是加了设计模式就自动可靠,需关注几个关键点:
- 状态变更必须原子化:使用 synchronized 块或乐观锁(如版本号 + CAS)防止并发重复支付
- 禁止外部直接修改状态字段:所有变更必须走 changeState(),便于审计和拦截
- 非法迁移要有明确兜底:比如从已完成状态触发取消,应记录告警并拒绝,而不是静默失败
- 状态类不持有业务数据:只通过方法参数接收 Order 实例,保持轻量与复用性
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











