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