设计模式-状态模式(State Pattern)结构|原理|优缺点|场景|示例

设计模式(分类) 设计模式(六大原则)

创建型(5种) 工厂方法 抽象工厂模式 单例模式 建造者模式 原型模式

结构型(7种) 适配器模式 装饰器模式 代理模式 ​​​​​​外观模式 桥接模式 组合模式 享元模式

行为型(11种) 策略模式 模板方法模式 观察者模式 迭代器模式 责任链模式 命令模式 备忘录模式 状态模式 访问者模式 中介者模式


状态模式(State Pattern)是一种行为设计模式,它允许对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。这种模式主要用于当一个对象的行为依赖于它的状态(即内部状态),并且它必须在运行时根据状态改变它的行为时。

结构: 状态模式主要包含以下几个角色:

  1. Context(环境类/上下文):定义了客户感兴趣的接口,并维护一个具体状态对象的引用,将与状态相关的操作委托给当前状态对象处理。
  2. State(抽象状态类):定义一个接口,用以封装使用上下文环境的各个状态所对应的行为。
  3. ConcreteState(具体状态类):实现抽象状态类定义的接口,每一个具体状态类对应上下文的一个具体状态,负责实现该状态下对应的行为。

原理:

  • 上下文对象持有一个状态对象的引用,这个状态对象决定了上下文对象的行为。
  • 当上下文对象的内部状态改变时,它会改变所持有的状态对象,从而改变其行为。
  • 上下文对象不需要知道具体状态类的细节,只需要通过抽象状态类的接口与状态对象交互。

优缺点: 优点:

  • 结构清晰,将状态相关的代码组织在一起,符合单一职责原则。
  • 将状态转换的逻辑封装在状态类中,使得状态转换逻辑与上下文对象分离,易于扩展新的状态和转换逻辑。
  • 提高了对象的可扩展性和可维护性。

缺点:

  • 如果状态过多,会导致类的个数增加,系统复杂度上升。
  • 状态模式的使用需要合理判断,避免过度设计。

应用场景:

  • UI控件的状态变化,如按钮的禁用/启用状态。
  • 状态机的实现,如ATM机的不同操作状态。
  • 工作流系统,如订单处理的不同阶段。

代码示例(以Java为例)

java 复制代码
// 抽象状态类
interface PlayerState {
    void play();
    void stop();
    void pause();
}

// 具体状态类:播放状态
class PlayingState implements PlayerState {
    @Override
    public void play() {
        System.out.println("Already playing.");
    }

    @Override
    public void stop() {
        System.out.println("Stopping the player.");
    }

    @Override
    public void pause() {
        System.out.println("Pausing the player.");
        // 可能会在这里切换到暂停状态(PauseState)
    }
}

// 具体状态类:暂停状态
class PausedState implements PlayerState {
    @Override
    public void play() {
        System.out.println("Resuming the player.");
    }

    @Override
    public void stop() {
        System.out.println("Stopping the player.");
    }

    @Override
    public void pause() {
        System.out.println("Player is already paused.");
    }
}

// 上下文类:播放器
class MediaPlayer {
    private PlayerState state;

    public MediaPlayer() {
        this.state = new StoppedState(); // 初始状态设为停止状态
    }

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

    public void play() {
        state.play();
    }

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

    public void pause() {
        state.pause();
    }
}

// 示例使用
public class StatePatternDemo {
    public static void main(String[] args) {
        MediaPlayer player = new MediaPlayer();
        player.play(); // 输出:Starting the player.
        player.pause(); // 输出:Pausing the player.
        player.stop(); // 输出:Stopping the player.
    }
}

在这个例子中,MediaPlayer是上下文,它维护了一个PlayerState的实例,通过调用play()stop()pause()等方法,实际上是由当前状态对象决定具体的行为。随着状态的改变,播放器的行为也会相应变化。

相关推荐
前端不太难7 小时前
HarmonyOS App 工程深水区:从能跑到可控
华为·状态模式·harmonyos
BD_Marathon10 小时前
设计模式——合成复用原则
设计模式·合成复用原则
书院门前细致的苹果20 小时前
设计模式大全:单例、工厂模式、策略模式、责任链模式
设计模式·责任链模式·策略模式
前端不太难1 天前
HarmonyOS 游戏上线前必做的 7 类极端场景测试
游戏·状态模式·harmonyos
光影少年1 天前
AI 前端 / 高级前端
前端·人工智能·状态模式
智商偏低1 天前
PostGIS+GeoServer+OpenLayers 数据加载无显示问题排查及自定义坐标系配置文档
状态模式
小王不爱笑1321 天前
序列化和反序列化
状态模式
程序员Sunday1 天前
说点不一样的。GPT-5.3 与 Claude Opus 4.6 同时炸场,前端变天了?
前端·gpt·状态模式
BD_Marathon1 天前
设计模式——依赖倒转原则
java·开发语言·设计模式
BD_Marathon1 天前
设计模式——里氏替换原则
java·设计模式·里氏替换原则