一、定义
状态模式(State Pattern):允许一个对象在其内部状态改变时,改变其行为。看起来就像是改变了这个对象的类。
通俗理解:对象内部状态不同,它“表现出来”的行为也不同,状态之间可自由转换。
二、适用场景
- 对象有多种状态,且状态之间存在明显切换逻辑;
- 状态对应的行为复杂,使用
if-else
难以维护; - 希望将状态行为解耦,提高扩展性和可读性;
- 适用于工作流引擎、订单系统、审批流、游戏角色等。
三、核心角色
角色 |
说明 |
Context |
环境类,持有当前状态,提供行为方法,并将请求委托给状态对象执行 |
State(状态接口) |
抽象状态,定义所有状态类的共同行为方法 |
ConcreteState |
具体状态类,实现不同状态下的行为逻辑 |
四、UML 类图
+-----------------+
| Context |
|-----------------|
| - state: State |
| + setState() |
| + request() |
+-----------------+
|
v
+-----------------+ +--------------------+
| State |<------> | ConcreteStateA |
| + handle() | +--------------------+
+-----------------+ | + handle() |
+--------------------+
+--------------------+
| ConcreteStateB |
+--------------------+
| + handle() |
+--------------------+
五、真实业务场景示例(含类角色与详细注释)
🧾 场景说明:
以 订单系统 为例,订单具有不同的状态,如:待支付
、已支付
、已发货
、已完成
。每种状态下支持的操作不同。
1. 抽象状态接口(State 角色)
// State:抽象状态接口,定义所有订单状态共有的操作
public interface OrderState {
void pay(); // 支付操作
void deliver(); // 发货操作
void receive(); // 收货操作
}
2. 具体状态类(ConcreteState 角色)
// ConcreteState:待支付状态,只能执行支付
public class PendingPaymentState implements OrderState {
private final OrderContext context;
public PendingPaymentState(OrderContext context) {
this.context = context;
}
@Override
public void pay() {
System.out.println("订单已支付,进入发货流程");
context.setState(new PaidState(context)); // 状态流转
}
@Override
public void deliver() {
System.out.println("当前为待支付状态,不能发货!");
}
@Override
public void receive() {
System.out.println("当前为待支付状态,不能收货!");
}
}
// ConcreteState:已支付状态,只能执行发货
public class PaidState implements OrderState {
private final OrderContext context;
public PaidState(OrderContext context) {
this.context = context;
}
@Override
public void pay() {
System.out.println("订单已支付,请勿重复操作!");
}
@Override
public void deliver() {
System.out.println("订单已发货,等待用户收货");
context.setState(new DeliveredState(context));
}
@Override
public void receive() {
System.out.println("订单未发货,不能收货!");
}
}
// ConcreteState:已发货状态,只能执行收货
public class DeliveredState implements OrderState {
private final OrderContext context;
public DeliveredState(OrderContext context) {
this.context = context;
}
@Override
public void pay() {
System.out.println("订单已支付,请勿重复操作!");
}
@Override
public void deliver() {
System.out.println("订单已发货,请勿重复发货!");
}
@Override
public void receive() {
System.out.println("用户已收货,订单完成");
context.setState(new CompletedState(context));
}
}
// ConcreteState:已完成状态,所有操作无效
public class CompletedState implements OrderState {
private final OrderContext context;
public CompletedState(OrderContext context) {
this.context = context;
}
@Override
public void pay() {
System.out.println("订单已完成,不能再支付");
}
@Override
public void deliver() {
System.out.println("订单已完成,不能再发货");
}
@Override
public void receive() {
System.out.println("订单已完成,不能再收货");
}
}
3. 环境类(Context 角色)
// Context:订单上下文,持有当前状态,并将操作委托给状态对象
public class OrderContext {
private OrderState currentState;
public OrderContext() {
// 默认状态为待支付
this.currentState = new PendingPaymentState(this);
}
public void setState(OrderState state) {
this.currentState = state;
}
public void pay() {
currentState.pay();
}
public void deliver() {
currentState.deliver();
}
public void receive() {
currentState.receive();
}
}
4. 客户端测试类(Client 角色)
public class StatePatternTest {
public static void main(String[] args) {
OrderContext order = new OrderContext();
order.pay(); // 支付
order.deliver(); // 发货
order.receive(); // 收货
// 再次尝试支付
order.pay(); // 已完成状态下操作无效
}
}
💡 类与角色对照表
类名 |
模式角色 |
说明 |
|
State |
抽象状态接口,定义行为方法 |
|
ConcreteState |
待支付状态 |
|
ConcreteState |
已支付状态 |
|
ConcreteState |
已发货状态 |
|
ConcreteState |
已完成状态 |
|
Context |
上下文,持有当前状态,行为委托给状态对象 |
|
Client |
客户端测试代码 |
六、优缺点分析(Pros & Cons)
✅ 优点
优点 |
说明 |
封装状态行为 |
每个状态行为独立,职责清晰,代码整洁 |
避免冗长条件判断 |
替代 或 ,更易扩展 |
状态可扩展 |
新增状态无需修改现有代码,符合开闭原则 |
更易维护 |
状态之间流转清晰,业务逻辑集中 |
❌ 缺点
缺点 |
说明 |
类数量增多 |
每个状态都是一个类,状态多时文件多 |
状态切换可能复杂 |
多状态之间依赖较多时,流转逻辑需要协调 |
若状态行为简单 |
使用模式反而显得结构臃肿 |
七、现实应用场景
场景 |
描述 |
审批流程 |
申请 → 审核中 → 审批通过/拒绝 |
订单流程 |
下单 → 支付 → 发货 → 收货 → 完成 |
游戏角色 |
正常状态 → 受伤状态 → 死亡状态 |
工作流引擎 |
各流程节点状态切换 |
TCP 连接 |
CLOSED、LISTEN、ESTABLISHED 等状态 |
八、总结(Summary)
状态模式是一种强大的行为型设计模式,适用于状态控制复杂、行为变化明显的业务流程。它通过封装状态行为,使状态逻辑独立清晰,大大提高了系统的可维护性和扩展性。