状态模式 (State)
📖 通俗理解
交通信号灯:
- 红灯 → 停
- 绿灯 → 行
- 黄灯 → 准备停
信号灯的行为取决于它的状态,不同状态有不同的行为。
状态模式就是:允许对象在内部状态改变时改变它的行为,对象看起来像是改变了它的类。
🎯 解决什么问题?
消除大量的条件分支语句(if-else / switch),把不同状态的行为封装到不同的状态类中。
// ❌ 没有状态模式
if (state == "红灯") {
stop();
} else if (state == "绿灯") {
go();
} else if (state == "黄灯") {
slowDown();
}
// ✅ 有状态模式
currentState.handle(); // 状态自己知道该做什么
🌰 生活中的例子
- 交通信号灯
- 订单状态:待支付 → 已支付 → 已发货 → 已完成
- 线程状态:新建 → 就绪 → 运行 → 阻塞 → 死亡
💻 Java 代码实现
场景:订单状态流转
/**
* 状态接口
*/
public interface OrderState {
void handle(Order order);
String getStateName();
}
/**
* 待支付状态
*/
public class PendingPayState implements OrderState {
@Override
public void handle(Order order) {
System.out.println("订单已支付!");
order.setState(new PaidState());
}
@Override
public String getStateName() {
return "待支付";
}
}
/**
* 已支付状态
*/
public class PaidState implements OrderState {
@Override
public void handle(Order order) {
System.out.println("订单已发货!");
order.setState(new ShippedState());
}
@Override
public String getStateName() {
return "已支付";
}
}
/**
* 已发货状态
*/
public class ShippedState implements OrderState {
@Override
public void handle(Order order) {
System.out.println("订单已签收!");
order.setState(new CompletedState());
}
@Override
public String getStateName() {
return "已发货";
}
}
/**
* 已完成状态
*/
public class CompletedState implements OrderState {
@Override
public void handle(Order order) {
System.out.println("订单已完成,无法继续操作");
}
@Override
public String getStateName() {
return "已完成";
}
}
/**
* 订单(上下文)
*/
public class Order {
private OrderState state;
private String orderId;
public Order(String orderId) {
this.orderId = orderId;
this.state = new PendingPayState();
}
public void setState(OrderState state) {
this.state = state;
}
public void nextStep() {
System.out.println("订单 " + orderId + " 当前状态: " + state.getStateName());
state.handle(this);
}
}
使用:
public class Client {
public static void main(String[] args) {
Order order = new Order("ORD001");
order.nextStep(); // 待支付 → 已支付
order.nextStep(); // 已支付 → 已发货
order.nextStep(); // 已发货 → 已完成
order.nextStep(); // 已完成,无法继续
}
}
输出:
订单 ORD001 当前状态: 待支付
订单已支付!
订单 ORD001 当前状态: 已支付
订单已发货!
订单 ORD001 当前状态: 已发货
订单已签收!
订单 ORD001 当前状态: 已完成
订单已完成,无法继续操作
⚠️ 状态模式 vs 策略模式
| 对比 | 状态模式 | 策略模式 |
|---|---|---|
| 目的 | 管理状态转换 | 切换算法 |
| 状态变化 | 自动切换 | 手动切换 |
| 知道彼此 | 状态之间知道 | 策略之间不知道 |
✅ 适用场景
- 对象的行为取决于状态
- 存在大量条件分支判断状态
- 状态转换需要明确的规则
小结
状态模式:把状态相关的行为封装到状态类中,状态改变时自动切换行为。
应用:工作流引擎、订单状态机、TCP 连接状态
👉 下一篇:策略模式
