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

时间:2024-05-02 09:17:38

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

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

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

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


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

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

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

原理:

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

优缺点: 优点:

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

缺点:

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

应用场景:

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

代码示例(以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()等方法,实际上是由当前状态对象决定具体的行为。随着状态的改变,播放器的行为也会相应变化。