文章目录
状态模式 (State Pattern)
状态模式 是一种 行为型设计模式,允许对象在其内部状态改变时改变其行为,使得对象看起来像是改变了其类。
原理
- 核心思想 :
- 将与对象状态相关的行为抽象到独立的状态类中。
- 通过在不同状态下切换状态类,改变对象的行为。
- 适用场景 :
- 对象的行为随状态的改变而改变。
- 状态的条件逻辑复杂,使用模式可以避免复杂的 if-else 或 switch-case。
- 参与角色 :
- Context(上下文类) :
- 管理状态,并向客户端提供统一的接口。
- 内部维护一个当前状态实例。
- State(状态接口) :
- 定义具体状态的行为接口。
- ConcreteState(具体状态类) :
- 实现状态接口,定义特定状态的行为。
- Context(上下文类) :
优点
- 消除条件逻辑 :
- 通过多态分离状态行为,避免复杂的条件判断语句。
- 增加扩展性 :
- 增加新状态无需修改已有代码,符合 开闭原则。
- 状态自包含 :
- 每个状态独立,易于管理。
缺点
- 增加类数量 :
- 每种状态都需要一个类,导致类的数量增加。
- 状态切换复杂性 :
- 如果状态间切换规则复杂,可能使上下文类难以管理。
示例代码
场景描述
模拟一个订单系统,订单可以处于不同状态(新建、支付、发货、完成)。不同状态下的行为有所不同。
1. 定义状态接口
java
// 状态接口
public interface OrderState {
void handle(OrderContext context);
}
2. 定义具体状态类
java
// 新建状态
public class NewState implements OrderState {
@Override
public void handle(OrderContext context) {
System.out.println("Order is in 'New' state.");
context.setState(new PaidState());
}
}
// 支付状态
public class PaidState implements OrderState {
@Override
public void handle(OrderContext context) {
System.out.println("Order is in 'Paid' state.");
context.setState(new ShippedState());
}
}
// 发货状态
public class ShippedState implements OrderState {
@Override
public void handle(OrderContext context) {
System.out.println("Order is in 'Shipped' state.");
context.setState(new CompletedState());
}
}
// 完成状态
public class CompletedState implements OrderState {
@Override
public void handle(OrderContext context) {
System.out.println("Order is in 'Completed' state.");
// 最终状态,无法再改变
}
}
3. 定义上下文类
java
// 上下文类
public class OrderContext {
private OrderState state;
public OrderContext() {
// 初始状态为新建
this.state = new NewState();
}
public void setState(OrderState state) {
this.state = state;
}
public void processOrder() {
state.handle(this);
}
}
4. 客户端代码
java
public class StatePatternExample {
public static void main(String[] args) {
OrderContext order = new OrderContext();
// 流程处理
order.processOrder(); // 新建 -> 支付
order.processOrder(); // 支付 -> 发货
order.processOrder(); // 发货 -> 完成
order.processOrder(); // 完成状态,无进一步操作
}
}
输出结果
text
Order is in 'New' state.
Order is in 'Paid' state.
Order is in 'Shipped' state.
Order is in 'Completed' state.
UML 类图
+-----------------+
| OrderState |
+-----------------+
| + handle(Context)|
+-----------------+
^
|
+------+-------+--------------------+-------------------+
| | | |
+-------------+ +-------------+ +-------------+ +-------------+
| NewState | | PaidState | | ShippedState| |CompletedState|
+-------------+ +-------------+ +-------------+ +-------------+
| + handle() | | + handle() | | + handle() | | + handle() |
+-------------+ +-------------+ +-------------+ +-------------+
^
|
+----------------------+
| OrderContext |
+----------------------+
| - state : OrderState |
| + setState(state) |
| + processOrder() |
+----------------------+
使用场景
- 状态转换系统 :
- 订单、流程审批等具有状态转换逻辑的系统。
- 游戏开发 :
- 玩家角色的状态切换(如站立、行走、跳跃等)。
- 工作流引擎 :
- 工单的状态流转(如创建、处理中、已完成)。
扩展与优化
- 状态复用 :
- 如果某些状态是无状态的,可以用单例模式实现。
- 状态机框架 :
- 对于复杂状态切换,可以使用现成的状态机框架(如 Spring Statemachine)。
- 状态数据分离 :
- 将状态行为与具体状态数据分离,适用于复杂业务逻辑。
小结
- 状态模式将状态与行为解耦,避免了复杂的条件逻辑。
- 适用于对象行为随状态变化的场景。
- 实现上要平衡状态类数量与复杂性的关系,防止类爆炸。