状态模式怎样管理状态转换 行为随状态改变方案

来源:Java编程网作者:深圳GEO公司头衔:草根站长
导读:本期聚焦于小伙伴创作的《状态模式怎样管理状态转换 行为随状态改变方案》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《状态模式怎样管理状态转换 行为随状态改变方案》有用,将其分享出去将是对创作者最好的鼓励。

状态模式的核心思想是将对象的状态封装成独立的类,当对象的状态发生改变时,其行为也会随之改变,让对象看起来好像修改了自身的类。这种模式非常适合处理对象有多个状态,且不同状态下行为差异明显的场景,比如订单状态流转、电梯运行状态控制等。

状态模式怎样管理状态转换 行为随状态改变方案

状态模式的核心组成

一个标准的状态模式结构包含三个核心角色:

  • 环境类(Context):维护当前状态的实例,对外提供操作接口,状态改变时由它触发状态切换。
  • 抽象状态类(State):定义所有状态共有的行为接口,不同具体状态类实现该接口的不同逻辑。
  • 具体状态类(ConcreteState):继承或实现抽象状态类,实现对应状态下的具体行为,同时可以定义状态转换的规则。

状态转换的两种实现方案

方案一:在环境类中控制状态转换

这种方案把状态转换的判断逻辑放在环境类中,具体状态类只负责实现当前状态下的行为,不关心状态怎么切换。适合状态转换规则比较固定,或者多个状态类共享相同转换逻辑的场景。

下面以电梯运行为例,电梯有停止、运行、故障三个状态,我们用这种方案实现状态管理:

// 抽象状态类
interface ElevatorState {
    // 上升行为
    void up(ElevatorContext context);
    // 下降行为
    void down(ElevatorContext context);
    // 停止行为
    void stop(ElevatorContext context);
}

// 停止状态
class StopState implements ElevatorState {
    @Override
    public void up(ElevatorContext context) {
        System.out.println("电梯从停止状态开始上升");
        // 切换到运行状态
        context.setState(new RunState());
    }

    @Override
    public void down(ElevatorContext context) {
        System.out.println("电梯从停止状态开始下降");
        context.setState(new RunState());
    }

    @Override
    public void stop(ElevatorContext context) {
        System.out.println("电梯已经处于停止状态,无需操作");
    }
}

// 运行状态
class RunState implements ElevatorState {
    @Override
    public void up(ElevatorContext context) {
        System.out.println("电梯正在上升中,无需重复操作");
    }

    @Override
    public void down(ElevatorContext context) {
        System.out.println("电梯正在下降中,无需重复操作");
    }

    @Override
    public void stop(ElevatorContext context) {
        System.out.println("电梯从运行状态切换到停止状态");
        context.setState(new StopState());
    }
}

// 故障状态
class FaultState implements ElevatorState {
    @Override
    public void up(ElevatorContext context) {
        System.out.println("电梯故障,无法上升");
    }

    @Override
    public void down(ElevatorContext context) {
        System.out.println("电梯故障,无法下降");
    }

    @Override
    public void stop(ElevatorContext context) {
        System.out.println("电梯故障,已停止运行");
    }
}

// 环境类
class ElevatorContext {
    private ElevatorState currentState;

    public ElevatorContext() {
        // 初始状态为停止状态
        this.currentState = new StopState();
    }

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

    public void up() {
        currentState.up(this);
    }

    public void down() {
        currentState.down(this);
    }

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

// 测试类
public class StatePatternDemo {
    public static void main(String[] args) {
        ElevatorContext elevator = new ElevatorContext();
        elevator.up();
        elevator.down();
        elevator.stop();
        // 模拟故障切换
        elevator.setState(new FaultState());
        elevator.up();
    }
}

方案二:在具体状态类中控制状态转换

这种方案把状态转换的逻辑放到具体状态类内部,环境类只需要调用状态的行为接口,不需要关心状态切换的细节。适合每个状态转换规则差异大,或者状态转换逻辑和当前状态强相关的场景。

我们继续用电梯的例子,调整实现方式:

// 抽象状态类
interface ElevatorState {
    void up(ElevatorContext context);
    void down(ElevatorContext context);
    void stop(ElevatorContext context);
    // 新增故障触发方法
    void triggerFault(ElevatorContext context);
}

// 停止状态
class StopState implements ElevatorState {
    @Override
    public void up(ElevatorContext context) {
        System.out.println("电梯从停止状态开始上升");
        context.setState(new RunState());
    }

    @Override
    public void down(ElevatorContext context) {
        System.out.println("电梯从停止状态开始下降");
        context.setState(new RunState());
    }

    @Override
    public void stop(ElevatorContext context) {
        System.out.println("电梯已经处于停止状态");
    }

    @Override
    public void triggerFault(ElevatorContext context) {
        System.out.println("停止状态的电梯触发故障");
        context.setState(new FaultState());
    }
}

// 运行状态
class RunState implements ElevatorState {
    @Override
    public void up(ElevatorContext context) {
        System.out.println("电梯正在上升中");
    }

    @Override
    public void down(ElevatorContext context) {
        System.out.println("电梯正在下降中");
    }

    @Override
    public void stop(ElevatorContext context) {
        System.out.println("电梯从运行状态切换到停止状态");
        context.setState(new StopState());
    }

    @Override
    public void triggerFault(ElevatorContext context) {
        System.out.println("运行状态的电梯触发故障");
        context.setState(new FaultState());
    }
}

// 故障状态
class FaultState implements ElevatorState {
    @Override
    public void up(ElevatorContext context) {
        System.out.println("故障电梯无法上升");
    }

    @Override
    public void down(ElevatorContext context) {
        System.out.println("故障电梯无法下降");
    }

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

    @Override
    public void triggerFault(ElevatorContext context) {
        System.out.println("电梯已经处于故障状态");
    }
}

// 环境类
class ElevatorContext {
    private ElevatorState currentState;

    public ElevatorContext() {
        this.currentState = new StopState();
    }

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

    public void up() {
        currentState.up(this);
    }

    public void down() {
        currentState.down(this);
    }

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

    public void triggerFault() {
        currentState.triggerFault(this);
    }
}

// 测试类
public class StatePatternDemo2 {
    public static void main(String[] args) {
        ElevatorContext elevator = new ElevatorContext();
        elevator.up();
        elevator.triggerFault();
        elevator.down();
    }
}

两种方案的对比与选择

我们可以通过下表对比两种方案的特点,根据实际场景选择:

对比维度环境类控制状态转换具体状态类控制状态转换
状态转换逻辑位置环境类具体状态类
状态类耦合度低,状态类不需要依赖其他状态高,状态类可能需要知道其他状态的存在
扩展性新增状态时可能需要修改环境类的转换逻辑新增状态时只需要实现对应行为,不需要修改环境类
适用场景状态转换规则统一、简单状态转换规则复杂、和状态强相关

行为随状态改变的实现要点

要让对象的行为跟随状态自动改变,需要注意以下几个要点:

  • 所有状态相关的行为都要定义在抽象状态接口中,避免遗漏。
  • 环境类只持有当前状态的引用,不直接实现状态相关的行为,把行为委托给当前状态对象执行。
  • 状态转换时只需要修改环境类持有的状态实例,后续的行为调用会自动使用新状态的逻辑。
  • 如果状态转换需要依赖外部条件,可以把条件判断放在状态转换的逻辑中,而不是放在环境类的业务代码里。

状态模式通过封装状态和行为,有效避免了大量的if-else或者switch-case判断,让代码结构更清晰,后续新增状态或者修改状态行为时,只需要新增或修改对应的状态类,不需要改动其他已有代码,符合开闭原则。在实际开发中,遇到对象状态多、状态行为差异大的场景,都可以优先考虑使用状态模式来实现状态转换和行为管理。

状态模式状态转换行为改变设计模式修改时间:2026-07-22 15:57:39

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。