首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >23种设计模式之状态模式

23种设计模式之状态模式

作者头像
紫风
发布2025-10-14 18:37:55
发布2025-10-14 18:37:55
8500
代码可运行
举报
运行总次数:0
代码可运行
状态模式  (State Pattern) 详细介绍

一、模式概述
  • 英文名称:State
  • 核心目标允许对象在其内部状态改变时改变它的行为,使得对象看起来像是修改了其类。
  • 设计思想:将状态抽象为独立类,对象的行为委托给当前状态对象,通过状态切换实现动态行为变化。

二、优缺点

优点

缺点

1. 消除冗余的条件分支,简化代码逻辑。

1. 类数量增加,每个状态对应一个类。

2. 符合开闭原则,新增状态无需修改现有代码。

2. 状态转换逻辑分散,维护成本可能增加。

3. 状态行为局部化,职责清晰。

3. 过度设计,简单状态机可能无需此模式。


三、应用场景
  1. 订单生命周期:待支付、已支付、已发货等状态。
  2. 电梯控制:开门、关门、运行、停止等状态。
  3. 游戏角色行为:站立、行走、攻击、跳跃等状态。
  4. 网络协议处理:TCP 连接状态(建立、监听、关闭)。

四、代码实现与注释
1. 状态接口(定义行为方法)
代码语言:javascript
代码运行次数:0
运行
复制
/**
 * 状态接口:定义电梯各状态下的行为方法
 */
public interface ElevatorState {
    void open();      // 开门
    void close();     // 关门
    void run();       // 运行
    void stop();      // 停止
}
2. 具体状态类(实现不同状态的行为)
代码语言:javascript
代码运行次数:0
运行
复制
/**
 * 开门状态:仅允许关门操作
 */
public class OpenState implements ElevatorState {
    private final ElevatorContext context;

    public OpenState(ElevatorContext context) {
        this.context = context;
    }

    @Override
    public void open() {
        System.out.println("电梯门已经是打开的");
    }

    @Override
    public void close() {
        System.out.println("电梯门关闭");
        context.setState(context.getCloseState());
    }

    @Override
    public void run() {
        System.out.println("电梯门未关闭,禁止运行");
    }

    @Override
    public void stop() {
        System.out.println("电梯已停止");
        context.setState(context.getStopState());
    }
}

/**
 * 关门状态:允许开门、运行或停止
 */
public class CloseState implements ElevatorState {
    private final ElevatorContext context;

    public CloseState(ElevatorContext context) {
        this.context = context;
    }

    @Override
    public void open() {
        System.out.println("电梯门打开");
        context.setState(context.getOpenState());
    }

    @Override
    public void close() {
        System.out.println("电梯门已经是关闭的");
    }

    @Override
    public void run() {
        System.out.println("电梯开始运行");
        context.setState(context.getRunState());
    }

    @Override
    public void stop() {
        System.out.println("电梯停止运行");
        context.setState(context.getStopState());
    }
}

// 运行状态和停止状态实现类似,此处省略,完整代码参考附录
3. 上下文类(维护当前状态)
代码语言:javascript
代码运行次数:0
运行
复制
/**
 * 电梯上下文:维护当前状态并提供状态切换方法
 */
public class ElevatorContext {
    private ElevatorState currentState;
    private final ElevatorState openState;
    private final ElevatorState closeState;
    private final ElevatorState runState;
    private final ElevatorState stopState;

    public ElevatorContext() {
        this.openState = new OpenState(this);
        this.closeState = new CloseState(this);
        this.runState = new RunState(this);
        this.stopState = new StopState(this);
        currentState = stopState; // 初始状态为停止
    }

    // 委托当前状态处理操作
    public void open() {
        currentState.open();
    }

    public void close() {
        currentState.close();
    }

    public void run() {
        currentState.run();
    }

    public void stop() {
        currentState.stop();
    }

    // 状态切换方法
    public void setState(ElevatorState state) {
        this.currentState = state;
    }

    // 获取状态实例的方法
    public ElevatorState getOpenState() {
        return openState;
    }

    public ElevatorState getCloseState() {
        return closeState;
    }

    public ElevatorState getRunState() {
        return runState;
    }

    public ElevatorState getStopState() {
        return stopState;
    }
}
4. 客户端调用
代码语言:javascript
代码运行次数:0
运行
复制
public class Client {
    public static void main(String[] args) {
        ElevatorContext elevator = new ElevatorContext();

        System.out.println("===== 初始状态:停止 =====");
        elevator.open();  // 停止状态允许开门

        System.out.println("\n===== 切换到开门状态 =====");
        elevator.close(); // 关门

        System.out.println("\n===== 切换到关门状态 =====");
        elevator.run();   // 运行

        System.out.println("\n===== 切换到运行状态 =====");
        elevator.stop();  // 停止
    }
}
5. 输出结果
代码语言:javascript
代码运行次数:0
运行
复制
===== 初始状态:停止 =====
电梯门打开

===== 切换到开门状态 =====
电梯门关闭

===== 切换到关门状态 =====
电梯开始运行

===== 切换到运行状态 =====
电梯停止运行

五、模式结构图
代码语言:javascript
代码运行次数:0
运行
复制
+----------------+          +----------------+
|   Context      | <>-----+ |   State        |
+----------------+          +----------------+
| -state:State   |          | +handle()      |
| +request()     |          +----------------+
+----------------+                 ^
       |                           |
       |                  +----------------+
       |                  | ConcreteStateA |
       |                  +----------------+
       |                  | +handle()      |
       |                  +----------------+
       |                  | ConcreteStateB |
       |                  +----------------+
       |                  | +handle()      |
       |                  +----------------+

六、与其他模式的关系
  1. 策略模式:状态模式根据状态改变行为,策略模式主动切换算法。
  2. 职责链模式:状态模式由状态对象处理请求,职责链模式由处理器链传递请求。
  3. 享元模式:若状态无内部数据,可用享元模式共享状态实例。

七、最佳实践
  1. 状态转换集中管理:在上下文类中定义转换规则,避免状态类耦合。
  2. 使用枚举简化:若状态有限且行为简单,可用枚举实现状态模式。
  3. 结合备忘录模式:保存和恢复历史状态,实现撤销/重做功能。

八、总结
  • 核心价值:通过封装状态行为,实现对象行为的动态切换,提升代码可维护性。
  • 适用场景:对象行为依赖状态且状态转换复杂的系统(如工作流、游戏、UI 控制)。
  • 关键实现:状态接口 + 具体状态类 + 上下文委托。

状态模式在 Java 生态中的典型应用包括:

  • 线程状态管理:如 Thread 的 NEWRUNNABLEBLOCKED 等状态。
  • 订单系统:电商平台订单状态流转。
  • 游戏引擎:角色或 NPC 的行为状态切换。

掌握该模式能有效管理复杂的状态转换逻辑,增强系统的扩展性和可读性。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-04-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 状态模式  (State Pattern) 详细介绍
    • 一、模式概述
    • 二、优缺点
    • 三、应用场景
    • 四、代码实现与注释
      • 1. 状态接口(定义行为方法)
      • 2. 具体状态类(实现不同状态的行为)
      • 3. 上下文类(维护当前状态)
      • 4. 客户端调用
      • 5. 输出结果
    • 五、模式结构图
    • 六、与其他模式的关系
    • 七、最佳实践
    • 八、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档