状态模式定义
允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。
状态模式结构图
状态模式角色介绍
环境类,Context,环境类又称为上下文类,它是拥有多种状态的对象。同时还维护一个抽象状态类State的实例,这个实例定义当前状态,在具体实现时,它是一个State子类的对象。
抽象状态类,State,一个抽象类或者接口,声明了各种不同状态对应的方法,而在其子类中实现类这些方法。
具体状态类,ConcreteState,它是抽象状态类的子类,每一个具体状态类对应环境的一个具体状态,状态子类都会持有环境类对象,当状态发生变更时,将变更的状态同步给环境对象。
状态模式结构代码
抽象状态类:
public interface State {
void handler();
}
具体状态类A:
public class ConcreteStateA implements State {
private Context context;
public ConcreteStateA(Context context) {
this.context = context;
}
public void handler() {
//执行状态A逻辑,然后修改状态变为状态B
System.out.println("ConcreteStateA.handler()");
context.setCurrentState(context.getStateB());
}
}
具体状态类B:
public class ConcreteStateB implements State {
private Context context;
public ConcreteStateB(Context context) {
this.context = context;
}
public void handler() {
//执行状态B逻辑,然后修改状态变为状态A
System.out.println("ConcreteStateB.handler()");
context.setCurrentState(context.getStateA());
}
}
环境类:
public class Context {
private State stateA;
private State stateB;
//当前状态默认为状态A
private State currentState;
//构造函数初始化状态,将当前对象同步给状态对象
public Context(){
this.stateA = new ConcreteStateA(this);
this.stateB = new ConcreteStateB(this);
currentState = this.stateA;
}
//设置当前状态
public void setCurrentState(State currentState) {
this.currentState = currentState;
}
//获取状态A
public State getStateA() {
return stateA;
}
//获取状态B
public State getStateB() {
return stateB;
}
public void request(){
this.currentState.handler();
}
}
客户端:
public class Client {
public static void main(String[] args) {
Context context = new Context();
context.request();
context.request();
}
}
状态模式运行机制
在状态模式中,我们将对象在不同状态下的行为封装到不同的状态类中,环境类操作状态时,只需要针对抽象状态类编程,所有状态行为的执行和变更同步都交给状态子类来完成。
环境类正向执行状态类进行状态操作,状态类执行完成后再来一个“回手掏”的动作把状态变更同步给环境类。
状态模式解决的核心问题
将状态具体逻辑操作和状态变更从环境类里抽出来,交给各个状态子类管理;也就是将环境类和状态操作进行解耦,状态逻辑变更和状态增减对环境类无影响,便于维护和扩展,符合开闭原则。