外观
一句话答案
将状态相关行为封装到状态类中,状态切换时切换状态对象,消除复杂 if-else,适合订单状态/审批流程。
核心要点
状态模式允许对象在内部状态改变时改变行为,看起来好像修改了它的类。不同状态被封装为独立的类,行为委托给当前状态对象。
核心区别:
| 维度 | 状态模式 | 策略模式 |
|---|---|---|
| 切换方式 | 状态在内部自动转换(对客户透明) | 策略由客户端外部指定 |
| 关注点 | 对象行为随状态变化而变化 | 同一行为有不同的算法实现 |
| 状态间关系 | 各状态之间有转换关系(状态机) | 各策略之间独立,无关联 |
| 客户端感知 | 客户端不知道有几种状态 | 客户端主动选择策略 |
| 典型场景 | 订单状态机、TCP 连接状态、审批流程 | 不同排序算法、不同支付方式 |
状态模式示例——订单状态机:
java
// 状态接口
public interface OrderState {
void pay(OrderContext ctx);
void ship(OrderContext ctx);
void confirm(OrderContext ctx);
}
// 待支付状态
public class PendingPayState implements OrderState {
public void pay(OrderContext ctx) {
System.out.println("支付成功");
ctx.setState(new PaidState()); // 内部自动转换到已支付状态
}
public void ship(OrderContext ctx) {
System.out.println("请先支付"); // 当前状态不允许发货
}
public void confirm(OrderContext ctx) {
System.out.println("请先支付");
}
}
// 已支付状态
public class PaidState implements OrderState {
public void pay(OrderContext ctx) {
System.out.println("已支付,请勿重复支付");
}
public void ship(OrderContext ctx) {
System.out.println("发货成功");
ctx.setState(new ShippedState()); // 转换到已发货状态
}
public void confirm(OrderContext ctx) {
System.out.println("请等待发货");
}
}一句话区分: 状态模式中,状态的切换是内部驱动的(对客户透明);策略模式中,策略的选择是外部指定的(由客户端决定)。
五、场景题
追问与易错
追问方向:
- 和策略模式区别?
- 订单状态机怎么用状态模式?
- Spring State Machine 了解吗?
易错点:
- ❌ 状态模式就是 if-else 替代——核心是状态转换封装
- ❌ 混淆状态和策略——状态随时间变化策略由客户端选
💡 记忆锚点
红绿灯模式:红灯状态只许停、绿灯状态才能走,灯自己按时间切换(内部驱动),司机不用管灯怎么变(对客户透明)。和策略模式的区别:策略是你自己选走哪条路,状态是灯替你决定能不能走。