状态设计模式(一种行为型设计模式,告别字段不同状态的ifelse操作)

解释:允许对象在内部状态改变时改变其行为,使得对象看起来好像修改了其类。

核心思想:将对象的状态抽象成独立的类,使得对象在不同状态下具有不同的行为。

主要角色:

  1. 环境类(Context):

1.1持有一个状态对象的引用(也就是那个私有成员变量(这个变量本来就是表示状态的嘛)),并在需要时将请求委托给当前状态对象处理。

1.2负责维护当前的状态,并在需要时将请求委托给当前状态对象处理。

1.3通过持有状态对象的引用(也就是那个私有成员变量),环境类可以动态地切换状态,并调用当前状态对象的方法来执行相应的操作。

2、抽象状态类(State):也就是抽象状态类(接口),定义了一个共享接口,该接口可以被具体状态实现。在抽象状态中声明了各种不同状态下的方法,用于处理特定的请求。

3、具体状态类(Concrete State):实现了抽象状态接口,定义了对象在特定状态下的行为。每个具体状态类代表了对象的一种状态。

环境类:

package com.example.designPattern.statePattern.example2;

/**
 * 环境类
 * 持有一个状态对象的引用,并在需要时将请求委托给当前状态对象处理。
 * 负责维护当前的状态,并在需要时将请求委托给当前状态对象处理。
 * 通过持有状态对象的引用,环境类可以动态地切换状态,并调用当前状态对象的方法来执行相应的操作。
 */
public class AudioPlayer {
    // 状态对象的引用就是 currentState 成员变量,在需要时将请求委托给当前状态对象处理。
    private AudioPlayerState state;
    // 这个setState 的参数是AudioPlayerState state 其中是一个用于接收传入的具体状态对象
    // 我们这里来理一下逻辑,其中我们AudioPlayerState 是一个接口,
    // 为什么 这个对象的类型是AudioPlayerState 因为PauseState、PlayingState、StopState实现了AudioPlayerState啊
    // 这三种状态都是AudioPlayerState
    // 作用是将传入的具体状态对象赋值给环境类 AudioPlayer 的 currentState 成员变量,从而改变音频播放器的当前状态。
    // 这样,在调用音频播放器的 play()、pause() 和 stop() 方法时,实际上是在调用当前状态对象的对应方法,从而实现了不同状态下的不同行为。
    public void setState(AudioPlayerState state){
        this.state = state;
    }
    // this 关键字代表当前对象,也就是 AudioPlayer 类的实例。
    // 将当前环境对象 this 作为参数传递给状态对象的方法。
    // 具体来说,this 代表的就是当前的 AudioPlayer 对象
    // 其中包含了私有成员变量 private AudioPlayerState state; 以及所有的公共方法 play()、pause() 和 stop()。
    public void play(){
        state.play(this);
    }
    public void pause(){
        state.pause(this);
    }
    public void stop(){
        state.stop(this);
    }

}

抽象状态类

package com.example.designPattern.statePattern.example2;

/**
 * 抽象状态类
 * 定义了一个共享接口,该接口可以被具体状态实现。在抽象状态中声明了各种不同状态下的方法,用于处理特定的请求。
 */
public interface AudioPlayerState {
    // 因为我们在AudioPlayer 类中传递的是this 这个也就是AudioPlayer 所以需要用AudioPlayer player 来接了没有问题
    void play(AudioPlayer player);
    void pause(AudioPlayer player);
    void stop(AudioPlayer player);

}

具体状态类

PauseState暂停状态:

package com.example.designPattern.statePattern.example2.impl;

import com.example.designPattern.statePattern.example2.AudioPlayer;
import com.example.designPattern.statePattern.example2.AudioPlayerState;

/**
 * 具体状态类
 * 实现了抽象状态接口,定义了对象在特定状态下的行为。每个具体状态类代表了对象的一种状态。
 * 暂停状态
 */
public class PauseState implements AudioPlayerState {
    @Override
    public void play(AudioPlayer player) {
        System.out.println("开始播放");
        // 这里是给 setState 传入 这个PlayingState对象(new PlayingState() 不就是new一个对象嘛)
        player.setState(new PlayingState());

    }

    @Override
    public void pause(AudioPlayer player) {
        System.out.println("已经暂停,无序再暂停");

    }

    @Override
    public void stop(AudioPlayer player) {
        System.out.println("停止播放");
        player.setState(new StopState());

    }

}

PlayingState播放状态:

package com.example.designPattern.statePattern.example2.impl;

import com.example.designPattern.statePattern.example2.AudioPlayer;
import com.example.designPattern.statePattern.example2.AudioPlayerState;

/**
 * 具体状态类
 * 实现了抽象状态接口,定义了对象在特定状态下的行为。每个具体状态类代表了对象的一种状态。
 * 播放状态
 */
public class PlayingState implements AudioPlayerState {
    @Override
    public void play(AudioPlayer player) {
        System.out.println("已经播放,无需重复播放");

    }

    @Override
    public void pause(AudioPlayer player) {
        System.out.println("暂停播放");
        player.setState(new PauseState());

    }

    @Override
    public void stop(AudioPlayer player) {
        System.out.println("停止播放");
        player.setState(new StopState());

    }
}

StopState 停止状态

package com.example.designPattern.statePattern.example2.impl;

import com.example.designPattern.statePattern.example2.AudioPlayer;
import com.example.designPattern.statePattern.example2.AudioPlayerState;

/**
 * 具体状态类
 * 实现了抽象状态接口,定义了对象在特定状态下的行为。每个具体状态类代表了对象的一种状态。
 */
public class StopState implements AudioPlayerState {
    @Override
    public void play(AudioPlayer player) {
        System.out.println("开始播放");
        player.setState(new PlayingState());

    }

    @Override
    public void pause(AudioPlayer player) {
        System.out.println("已经停止播放,无法暂停");
        player.setState(new PauseState());


    }

    @Override
    public void stop(AudioPlayer player) {
        System.out.println("已经暂停,无法再次暂停播放");
    }

}

测试类:

package com.example.designPattern.statePattern.example2;

import com.example.designPattern.statePattern.example2.impl.PauseState;
import com.example.designPattern.statePattern.example2.impl.PlayingState;
import com.example.designPattern.statePattern.example2.impl.StopState;

public class StatePatternExample {
    public static void main(String[] args) {
        AudioPlayer player  = new AudioPlayer();

        player.setState(new StopState());
        System.out.println("------第一种情况------");
        player.play();
        player.play();

        player.setState(new PlayingState());
        System.out.println("------第二种情况------");
        player.play();
        player.pause();
        player.stop();
        player.pause();

        player.setState(new PauseState());
        System.out.println("------第三种情况------");
        player.play();
        player.play();



    }
}

思考:当我们想要进行状态传递时候我们执行完逻辑后进行setState然后将对应的状态对象传递进去就ok了

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐