状态模式
一、定义
当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类。
状态模式的通用类图如下
State是抽象状态角色,负责对象状态定义,并且封装环境角色以实现状态切换;ConcreteState是具体状态角色,完成本状态的行为管理以及趋向状态管理(本状态如何股过度到其他状态);Context是环境角色,定义客户端需要的接口,并且负责具体转台的切换;
状态模式的通用源码
-
抽象状态角色
public abstract class State { //定义一个环境角色,提供子类访问 protected Context context; //设置环境角色 public void setContext(Context _context){ this.context = _context; } //行为1 public abstract void handle1(); //行为2 public abstract void handle2(); }
-
状态角色
public class ConcreteState1 extends State { @Override public void handle1() { //本状态下必须处理的逻辑 } @Override public void handle2() { //设置当前状态为stat2 super.context.setCurrentState(Context.STATE2); //过渡到state2状态,由Context实现 super.context.handle2(); } }
public class ConcreteState2 extends State { @Override public void handle1() { //设置当前状态为state1 super.context.setCurrentState(Context.STATE1); //过渡到state1状态,由Context实现 super.context.handle1(); } @Override public void handle2() { //本状态下必须处理的逻辑 } }
-
环境角色
public class Context { //把状态对象声明为静态常量,有几个状态对象就声明几个静态常量 //环境角色具有状态抽象角色定义的所有行为,具体执行使用委托方式。 //定义状态 public final static State STATE1 = new ConcreteState1(); public final static State STATE2 = new ConcreteState2(); //当前状态 private State CurrentState; //获得当前状态 public State getCurrentState() { return CurrentState; } //设置当前状态 public void setCurrentState(State currentState) { this.CurrentState = currentState; //切换状态 this.CurrentState.setContext(this); } //行为委托 public void handle1(){ this.CurrentState.handle1(); } public void handle2(){ this.CurrentState.handle2(); } }
-
场景类
public class Client { public static void main(String[] args) { //定义环境角色 Context context = new Context(); //初始化状态 context.setCurrentState(new ConcreteState1()); //行为执行 context.handle1(); context.handle2(); } }
二、状态模式的优点
-
结构清晰
避免了过多的switch…case或者if…else语句,避免了程序的复杂性,提高系统的可维护性
-
遵循设计原则
遵循开闭原则和单一职责原则,每个状态都是一个子类,要增加一个状态就增加一个子类,要自改状态,只修改“那个状态”子类即可
-
封装性好
状态变换放置到类的内部实现,外部的调用不知道类内部如何实现 状态和行为 变换
三、状态模式的使用场景
-
行为随状态改变而改变的场景
如权限设计,人员的转态不同即使执行形同的行为结果也会不同。
-
条件、分支判断语句的替代者
在程序中大量使用switch语句或者if语句会导致程序结构不清晰,逻辑混乱,使用状态模式可以很好的避开这个问题
注意:状态模式适用于当某个对象在它的状态发生改变时,它的行为也随着发生比较大的变化,也就是在行为受状态约束的情况下可以使用状态模式,而且使用时对象的状态最好不要超过5个