【设计模式】三十一、状态模式
系列文章|源码
https://github.com/tyronczt/design-mode-learn
文章目录
- 系列文章|源码
- 一、模式核心思想
- 二、模式结构
- 三、Java代码示例:订单状态管理
- 1. 定义状态接口
- 2. 实现具体状态类
- 3. 上下文类(Context)
- 4. 客户端调用
- 5. 运行截图
- 四、状态模式的核心优势
- 1. 消除复杂条件分支
- 2. 高扩展性与维护性
- 3. 符合开闭原则(OCP)
- 4. 状态转换显式化
- 5. 提升代码复用性
- 五、适用场景
- 六、与其他模式的协作
- 七、总结
- 参考
一、模式核心思想
状态模式(State Pattern)是一种行为型设计模式,允许对象在其内部状态改变时改变自身行为。其核心思想是将对象的状态抽象为独立类,通过委托状态对象处理与状态相关的逻辑,从而消除复杂的条件判断语句(如if-else
或switch-case
),提升代码的可维护性和扩展性。
二、模式结构
状态模式包含三个核心角色:
角色 | 职责 | Java实现示例 |
---|---|---|
Context(上下文) | 维护当前状态对象的引用,并将状态相关操作委托给具体状态类 | 持有State 接口实例,提供状态切换方法(如setState() ) |
State(状态接口) | 定义状态行为的抽象方法,约束具体状态类的实现 | 接口或抽象类(如OrderState 接口定义handleState() 方法) |
ConcreteState(具体状态) | 实现特定状态下的行为逻辑,并触发状态转换 | 实现State 接口的类(如PayOrder 处理支付状态逻辑) |
三、Java代码示例:订单状态管理
以下是一个简化的订单状态流转示例,展示状态模式的实际应用:
1. 定义状态接口
public interface IOrderState {
/**
* 处理订单上下文
*/
void handle(OrderContext context);
}
2. 实现具体状态类
// 待支付状态
public class PendingPaymentState implements IOrderState {
// 实现接口中的handle方法
@Override
public void handle(OrderContext context) {
System.out.println("订单待支付,跳转支付页面...");
context.setState(new PaidState()); // 状态切换
}
}
// 已支付状态
public class PaidState implements IOrderState {
@Override
public void handle(OrderContext context) {
System.out.println("订单已支付,准备发货...");
context.setState(new ShippedState());
}
}
// 已发货状态
public class ShippedState implements IOrderState {
@Override
public void handle(OrderContext context) {
System.out.println("订单已发货,待收货...");
}
}
3. 上下文类(Context)
public class OrderContext {
private IOrderState state;
public void setState(IOrderState state) {
this.state = state;
}
public void process() {
state.handle(this);
}
}
4. 客户端调用
public class Client {
public static void main(String[] args) {
// 创建一个订单上下文实例
OrderContext order = new OrderContext();
// 设置订单的初始状态为待支付
order.setState(new PendingPaymentState());
order.process(); // 输出:订单待支付,跳转支付页面...
order.process(); // 输出:订单已支付,准备发货...
order.process(); // 输出:订单已发货,待收货...
}
}
5. 运行截图
四、状态模式的核心优势
1. 消除复杂条件分支
• 问题:传统方式需通过大量if-else
判断当前状态(如订单状态),代码臃肿且难以维护。
• 解决:每个状态封装独立类,逻辑清晰(如PendingState
仅处理待支付逻辑)。
2. 高扩展性与维护性
• 新增状态:只需添加新状态类(如新增CanceledState
),无需修改现有代码。
• 修改行为:仅需调整对应状态类的逻辑,避免牵一发而动全身。
3. 符合开闭原则(OCP)
• 对扩展开放:新状态不影响原有系统。
• 对修改关闭:上下文类无需因状态增减而改动。
4. 状态转换显式化
• 状态流转由具体状态类控制(如PaidState
触发向ShippedState
的转换),逻辑集中且透明。
5. 提升代码复用性
• 公共逻辑可抽取至抽象类(如状态切换的公共方法),减少重复代码。
五、适用场景
- 多状态对象:如订单状态(待支付/已发货)、任务状态(进行中/已完成)。
- 行为依赖状态:如游戏角色状态(攻击/防御)触发不同动作。
- 需动态切换逻辑:如电梯运行状态(上行/停止)对应不同控制规则。
六、与其他模式的协作
• 策略模式:状态模式强调状态驱动行为,策略模式侧重算法选择(如加密算法切换)。
• 观察者模式:结合使用可实现状态变更实时通知(如订单状态更新触发邮件通知)。
七、总结
状态模式通过解耦状态与行为,解决了复杂状态逻辑的维护难题。其优势在Java中尤为突出,结合接口和多态特性,能高效实现灵活的状态管理。实际开发中,建议在状态较多或流转复杂的场景(如电商、游戏)优先采用此模式。
项目代码:https://github.com/tyronczt/design-mode-learn/tree/main/design-mode-learn-31
参考
7.状态设计模式 - 掘金
状态设计模式