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作业本身都具有如下几种状态,草稿状态,执行中状态,运行状态,停止状态,下线状态,中间会涉及修改,提交,重置,重启等动作进而进行状态之间的转换,那么这行行为以及状态就可以通过状态模式来进行解决。