设计模式-状态模式

该博客介绍了状态模式在软件设计中的应用,通过播放器和计算引擎作业管理两个案例展示了如何使用状态模式来处理对象在不同状态下的行为变化。状态模式允许对象在内部状态改变时改变其行为,减少了条件语句的复杂性,使得代码更易于理解和维护。然而,当状态数量庞大时,可能会导致类的数量增多,系统复杂度增加。博客提到了状态模式与享元模式的联动,并提供了具体的Java代码实现。
摘要由CSDN通过智能技术生成

1 含义:

允许一个对象在其内部状态改变时,改变他的行为

2 适用场景:

一个对象允许存在多个状态(不同状态行为不同),且状态可相互转换。
一般来说,如果一个代码里面出现了特别的if else,就可以考虑一下是否可以转换出状态模式

3 优缺点

优点:

  • 将不同的状态隔离
  • 把各种状态的转换逻辑,分不到各个State的子类中,减少相互间的依赖
  • 增加新的状态也比较简单,扩展容易

缺点:
状态多的业务场景会导致类的数目很多,系统变得复杂。
比如当我们设计的系统涉及到几百个状态的时候,这时候使用或者不使用状态模式,都有可能导致系统变得复杂,这时候可能就需要分组,分而治之的分别处理等思路。

状态模式相关联动设计模式-联动享元模式。

4 结构

在这里插入图片描述

5 案例

5.1 播放器

举例播放器,一般有播放,暂停,快进,停止, 4种状态。 这几种状态之间的转换关系:
在这里插入图片描述

举例:

在这里插入图片描述

代码如下:
统一的State抽象类:

package designpatterns.principle.state.player;

public abstract class PlayerState {



    public void refresh() {
        System.out.println("任意状态下,都可以执行刷新操作");
    }

    public abstract void play();

    public abstract void speed();

    public abstract void stop();

    public abstract void close();

}

各个状态的子类实现:

package designpatterns.principle.state.player;

public class PlayerPlayState  extends PlayerState{

    PlayContext playContext;

    public PlayerPlayState(PlayContext playContext) {
        this.playContext = playContext;
    }

    @Override
    public void play() {

        System.out.println("开始播放");
    }

    @Override
    public void speed() {

        System.out.println("播放转换快进状态");
        playContext.setPlayerState(playContext.getPlayerSpeedState());
    }

    @Override
    public void stop() {

        System.out.println("播放转换暂停状态");
        playContext.setPlayerState(playContext.getPlayerStopState());
    }

    @Override
    public void close() {

        System.out.println("播放转换停止关闭状态");
        playContext.setPlayerState(playContext.getPlayerCloseState());
    }
}
package designpatterns.principle.state.player;

public class PlayerSpeedState extends PlayerState{

    PlayContext playContext;

    public PlayerSpeedState(PlayContext playContext) {
        this.playContext = playContext;
    }

    @Override
    public void play() {
        System.out.println("快进状态转换播放状态");
        playContext.setPlayerState(playContext.getPlayerPlayState());
    }

    @Override
    public void speed() {
        System.out.println("快进");
    }

    @Override
    public void stop() {

        System.out.println("快进状态转换成暂停状态");
        playContext.setPlayerState(playContext.getPlayerStopState());
    }

    @Override
    public void close() {

        System.out.println("快进状态转换成关闭状态");
        playContext.setPlayerState(playContext.getPlayerCloseState());
    }
}
package designpatterns.principle.state.player;

public class PlayerStopState extends PlayerState{

    PlayContext playContext;

    public PlayerStopState(PlayContext playContext) {
        this.playContext = playContext;
    }

    @Override
    public void play() {

        System.out.println("暂停状态转换成播放状态");
        playContext.setPlayerState(playContext.getPlayerPlayState());
    }

    @Override
    public void speed() {

        System.out.println("暂停状态转换成快进状态");
        playContext.setPlayerState(playContext.getPlayerSpeedState());
    }

    @Override
    public void stop() {

        System.out.println("暂停");
    }

    @Override
    public void close() {

        System.out.println("暂停状态转换成关闭状态");
        playContext.setPlayerState(this.playContext.getPlayerCloseState());
    }
}
package designpatterns.principle.state.player;

public class PlayerCloseState extends PlayerState{

    PlayContext playContext;

    public PlayerCloseState(PlayContext playContext) {
        this.playContext = playContext;
    }

    @Override
    public void play() {

        System.out.println("停止状态无法转换播放状态");
    }

    @Override
    public void speed() {

        System.out.println("停止状态无法转换快进状态");
        playContext.setPlayerState(playContext.getPlayerSpeedState());
    }

    @Override
    public void stop() {

        System.out.println("停止状态无法转换暂停状态");
        playContext.setPlayerState(playContext.getPlayerStopState());
    }

    @Override
    public void close() {

        System.out.println("关闭");

    }
}

Contex上下文

package designpatterns.principle.state.player;

public class PlayContext {


    private PlayerState playerState;

    private PlayerState playerPlayState;
    private PlayerState playerSpeedState;
    private PlayerState playerStopState;
    private PlayerState playerCloseState;


    public PlayContext() {
        this.playerPlayState = new PlayerPlayState(this);
        this.playerSpeedState = new PlayerSpeedState(this);
        this.playerStopState = new PlayerStopState(this);
        this.playerCloseState = new PlayerCloseState(this);

        // 设置初始状态
        this.playerState = playerStopState;
    }

    public void setPlayerState(PlayerState playerState) {
        this.playerState = playerState;
    }

    public PlayerState getPlayerPlayState() {
        return playerPlayState;
    }

    public PlayerState getPlayerSpeedState() {
        return playerSpeedState;
    }

    public PlayerState getPlayerStopState() {
        return playerStopState;
    }

    public PlayerState getPlayerCloseState() {
        return playerCloseState;
    }

    public void play() {
        this.playerState.play();
    }

    public void refresh() {
        this.playerState.refresh();
    }

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

    public void speed() {
        this.playerState.speed();
    }

    public void close() {
        this.playerState.close();
    }



}

测试类:

package designpatterns.principle.state.player;

public class Test {


    public static void main(String[] args) {
        PlayContext playContext = new PlayContext();

        playContext.play();

        playContext.speed();
        playContext.speed();

        playContext.play();
        playContext.stop();
        playContext.close();
        playContext.play();
    }
}

5.2 计算引擎作业管理

针对计算引擎作业,比如Spark, Flink, 的JOB作业本身都具有如下几种状态,草稿状态,执行中状态,运行状态,停止状态,下线状态,中间会涉及修改,提交,重置,重启等动作进而进行状态之间的转换,那么这行行为以及状态就可以通过状态模式来进行解决。

图计算与算法公众号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值