状态模式
状态模式的场景,就是一部电梯的运行,开,关,运行,停止。如果不用状态模式,会出现很多switch case或者if else 进行电梯状态的判断。
状态模式,就是一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其他类。
状态模式的3个角色:
- State 抽象状态角色。 负责对象状态定义,封装环境角色以实现状态切换。
- ConcreteState 具体状态角色。 每一个具体状态角色必须完成2个职责:1. 本状态的行为管理。2.趋向状态管理,通俗的说是本状态要做的事,以及本状态如何过渡到其他状态的。
- 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() {
//设置当前状态2
super.context.setCurrentState(Context.STATE2);
//过渡到STATE2 ,由Context实现
super.context.handle2();
}
}
public class ConcreteState2 extends State{
@Override
public void handle1() {
//设置当前状态1
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 Context(){
}
public State getCurrentState(){
return this.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 mian(String[] args){
Context context=new Context();
context.setCurrentState(new ConcreteState1());
context.handle1();
context.handle2();
}
}
状态模式的优点
- 结构清晰。避免了过多的switch/case 或if/else 避免了程序的复杂性,提高系统的可维护性
- 遵循设计原则。 符合开闭原则和单一职责原则。 每个状态是一个子类,增加状态就增加子类,修改状态就修改子类。
- 封装性较好。状态变换放到类的内部来实现。外部调用不知道内部如何实现状态和行为的变换。
状态模式的缺点
- 子类会太多,造成类膨胀。 这时候可以在数据库中建立一个状态表,然后根据状态执行相应的操作。
状态模式的使用场景
- 行为随状态改变而改变。
- 分支条件过多