【设计模式】三十一、状态模式

系列文章|源码

https://github.com/tyronczt/design-mode-learn

文章目录

一、模式核心思想

状态模式(State Pattern)是一种行为型设计模式 ,允许对象在其内部状态改变时改变自身行为。其核心思想是将对象的状态抽象为独立类 ,通过委托状态对象处理与状态相关的逻辑,从而消除复杂的条件判断语句(如if-elseswitch-case),提升代码的可维护性和扩展性。

二、模式结构

状态模式包含三个核心角色:

角色 职责 Java实现示例
Context(上下文) 维护当前状态对象的引用,并将状态相关操作委托给具体状态类 持有State接口实例,提供状态切换方法(如setState()
State(状态接口) 定义状态行为的抽象方法,约束具体状态类的实现 接口或抽象类(如OrderState接口定义handleState()方法)
ConcreteState(具体状态) 实现特定状态下的行为逻辑,并触发状态转换 实现State接口的类(如PayOrder处理支付状态逻辑)

三、Java代码示例:订单状态管理

以下是一个简化的订单状态流转示例,展示状态模式的实际应用:

1. 定义状态接口

java 复制代码
public interface IOrderState {
    /**
     * 处理订单上下文
     */
    void handle(OrderContext context);
}

2. 实现具体状态类

java 复制代码
// 待支付状态
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)

java 复制代码
public class OrderContext {
    private IOrderState state;

    public void setState(IOrderState state) {
        this.state = state;
    }

    public void process() {
        state.handle(this);
    }
}

4. 客户端调用

java 复制代码
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. 提升代码复用性

• 公共逻辑可抽取至抽象类(如状态切换的公共方法),减少重复代码。

五、适用场景

  1. 多状态对象:如订单状态(待支付/已发货)、任务状态(进行中/已完成)。
  2. 行为依赖状态:如游戏角色状态(攻击/防御)触发不同动作。
  3. 需动态切换逻辑:如电梯运行状态(上行/停止)对应不同控制规则。

六、与其他模式的协作

策略模式 :状态模式强调状态驱动行为 ,策略模式侧重算法选择 (如加密算法切换)。

观察者模式:结合使用可实现状态变更实时通知(如订单状态更新触发邮件通知)。

七、总结

状态模式通过解耦状态与行为,解决了复杂状态逻辑的维护难题。其优势在Java中尤为突出,结合接口和多态特性,能高效实现灵活的状态管理。实际开发中,建议在状态较多或流转复杂的场景(如电商、游戏)优先采用此模式。

项目代码:https://github.com/tyronczt/design-mode-learn/tree/main/design-mode-learn-31

参考

7.状态设计模式 - 掘金

状态设计模式

相关推荐
杨充21 小时前
10.可测试性实战设计
设计模式·开源·代码规范
杨充21 小时前
9.重构十二式的实战
设计模式·开源·代码规范
杨充21 小时前
6.设计原则的全景图
设计模式·开源·全栈
杨充21 小时前
2.面向对象的特性
设计模式
杨充21 小时前
7.SOLID原则案例汇
设计模式·开源·全栈
杨充21 小时前
8.反模式与坏味道
设计模式·开源·代码规范
杨充21 小时前
3.接口vs抽象类比较
设计模式
咖啡八杯1 天前
文法、BNF与AST
java·设计模式·解释器模式·ast·文法
咖啡八杯1 天前
GoF设计模式——解释器模式
java·后端·spring·设计模式