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 PlayerPlayStateextends 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作业本身都具有如下几种状态,草稿状态,执行中状态,运行状态,停止状态,下线状态,中间会涉及修改,提交,重置,重启等动作进而进行状态之间的转换,那么这行行为以及状态就可以通过状态模式来进行解决。
【java|设计模式-状态模式】
文章图片
推荐阅读
- java|设计模式第一回
- Java|Mybatis 一级缓存和二级缓存的使用
- java|linux连接Redis客户端
- 《Effective Java》第54条(返回零长度的数组或者集合,而不是null)
- MySQL|MySQL慢SQL调优
- 网络|ARP防御篇-如何揪出“内鬼”并“优雅的还手”
- 安全|Apache Commons Configuration远程代码执行漏洞(CVE-2022-33980)分析&复现
- Java|MySQL调优之SQL语句(如何写出高性能SQL语句())
- java|2022年最新阿里java面试题(java初级+中级+高级面试题(附答案))