🧭 一、什么是状态机(State Machine)
状态机(State Machine)是一种非常常见的设计模式,
它通过**状态(State)与事件(Event)**的组合来驱动程序的执行逻辑。
在状态机中,一个对象在任意时刻都处于某个“状态”,
当触发特定的“事件”后,它会**迁移(Transition)**到另一个状态,并执行对应的逻辑。
⚙️ 二、核心思想
状态机由三个核心要素组成:
| 要素 | 说明 |
|---|---|
| State(状态) | 当前对象的状态,如 PENDING、PAID、SHIPPED |
| Event(事件) | 导致状态转换的触发事件,如 PAY_SUCCESS、SHIP |
| Transition(状态迁移) | 从一个状态到另一个状态的转变过程,可附带逻辑操作 |
💡 三、完整案例:订单状态流转
下面是一个完整的可运行示例:
演示订单从 待支付 → 已支付 → 已发货 → 已完成 的过程。
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
// 定义状态
enum OrderState {
PENDING, // 待支付
PAID, // 已支付
SHIPPED, // 已发货
COMPLETED, // 已完成
CANCELED // 已取消
}
// 定义事件
enum OrderEvent {
PAY_SUCCESS,
SHIP,
DELIVER,
CANCEL
}
// 状态机类
class StateMachine<S, E> {
private S currentState;
private final Map<String, Transition<S, E>> transitions = new HashMap<>();
// 定义状态转换结构
static class Transition<S, E> {
S from;
E event;
S to;
Runnable action;
Transition(S from, E event, S to, Runnable action) {
this.from = from;
this.event = event;
this.to = to;
this.action = action;
}
}
public StateMachine(S initState) {
this.currentState = initState;
}
// 添加状态迁移
public void addTransition(S from, E event, S to, Runnable action) {
transitions.put(key(from, event), new Transition<>(from, event, to, action));
}
// 触发事件
public void trigger(E event) {
String k = key(currentState, event);
Transition<S, E> t = transitions.get(k);
if (t == null) {
System.out.println("⚠️ 无效的状态转换:" + currentState + " 不能触发事件 " + event);
return;
}
System.out.println("➡️ 状态变化:" + currentState + " → " + t.to);
t.action.run();
currentState = t.to;
}
public S getCurrentState() {
return currentState;
}
private String key(S s, E e) {
return s.toString() + "_" + e.toString();
}
}
public class OrderStateMachineDemo {
public static void main(String[] args) {
StateMachine<OrderState, OrderEvent> sm = new StateMachine<>(OrderState.PENDING);
// 添加状态流转规则
sm.addTransition(OrderState.PENDING, OrderEvent.PAY_SUCCESS, OrderState.PAID,
() -> System.out.println("✅ 订单支付成功,准备发货"));
sm.addTransition(OrderState.PAID, OrderEvent.SHIP, OrderState.SHIPPED,
() -> System.out.println("🚚 订单已发货"));
sm.addTransition(OrderState.SHIPPED, OrderEvent.DELIVER, OrderState.COMPLETED,
() -> System.out.println("🎉 订单已完成"));
sm.addTransition(OrderState.PENDING, OrderEvent.CANCEL, OrderState.CANCELED,
() -> System.out.println("❌ 订单已取消"));
// 流程执行
System.out.println("初始状态:" + sm.getCurrentState());
sm.trigger(OrderEvent.PAY_SUCCESS);
sm.trigger(OrderEvent.SHIP);
sm.trigger(OrderEvent.DELIVER);
sm.trigger(OrderEvent.CANCEL); // 无效操作
System.out.println("最终状态:" + sm.getCurrentState());
}
}
🧩 四、运行结果
初始状态:PENDING
➡️ 状态变化:PENDING → PAID
✅ 订单支付成功,准备发货
➡️ 状态变化:PAID → SHIPPED
🚚 订单已发货
➡️ 状态变化:SHIPPED → COMPLETED
🎉 订单已完成
⚠️ 无效的状态转换:COMPLETED 不能触发事件 CANCEL
最终状态:COMPLETED
🧠 五、总结与扩展
✅ 优点:
- 逻辑清晰:用“状态+事件”代替多层 if/else。
- 可扩展性强:增加新状态只需添加规则,不破坏原有逻辑。
- 便于维护:结构化定义状态迁移,易于调试。
💡 扩展方向:
- 支持异步执行(如结合
CompletableFuture) - 持久化状态(如在数据库中记录状态变化)
- 与 Spring StateMachine 集成,支持复杂业务流转