java|设计模式-状态模式

1 含义: 允许一个对象在其内部状态改变时,改变他的行为
2 适用场景: 一个对象允许存在多个状态(不同状态行为不同),且状态可相互转换。
一般来说,如果一个代码里面出现了特别的if else,就可以考虑一下是否可以转换出状态模式
3 优缺点 优点:

  • 将不同的状态隔离
  • 把各种状态的转换逻辑,分不到各个State的子类中,减少相互间的依赖
  • 增加新的状态也比较简单,扩展容易
缺点:
状态多的业务场景会导致类的数目很多,系统变得复杂。
比如当我们设计的系统涉及到几百个状态的时候,这时候使用或者不使用状态模式,都有可能导致系统变得复杂,这时候可能就需要分组,分而治之的分别处理等思路。
状态模式相关联动设计模式-联动享元模式。
4 结构 java|设计模式-状态模式
文章图片

5 案例 5.1 播放器
举例播放器,一般有播放,暂停,快进,停止, 4种状态。 这几种状态之间的转换关系:
java|设计模式-状态模式
文章图片

举例:
java|设计模式-状态模式
文章图片

代码如下:
统一的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|设计模式-状态模式
文章图片

    推荐阅读