定义:当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类
State抽象状态角色:接口或抽象类,负责对象状态的定义,并且封装环境角色以实现状态切换。
ConcreteState具体状态角色:需要完成两个职责,在本状态下要做的事以及如何过渡到其他状态
Context环境角色:定义客户端需要的接口,并且负责具体状态的切换
abstract class State{
protected Context context;
public void setState(Context context){
this.context = context;
}
public abstract void handle1();
public abstract void handle2();
}
class ConcreteState1 extends State {
@Override
public void handle1() {
System.out.println("ConcreteState1 handle1");
}
@Override
public void handle2() {
System.out.println("ConcreteState1 handle2");
//设置当前状态为state2,并过渡到对应状态 都是由context类进行转接
super.context.setCurState(Context.STATE2);
super.context.handle2();
}
}
class ConcreteState2 extends State {
@Override
public void handle1() {
System.out.println("ConcreteState2 handle1");
super.context.setCurState(Context.STATE1);
super.context.handle1();
}
@Override
public void handle2() {
System.out.println("ConcreteState2 handle2");
}
}
class Context {
public final static State STATE1 = new ConcreteState1();
public final static State STATE2 = new ConcreteState2();
private State currectState;
public State getState(){
return currectState;
}
//设置当前状态
public void setCurState(State state){
this.currectState = state;
this.currectState.context = this;
}
//行为委托
public void handle1(){
this.currectState.handle1();
}
public void handle2(){
this.currectState.handle2();
}
}
public class Test {
public static void main(String[] args){
Context context = new Context();
context.setCurState(new ConcreteState1());
context.handle1();
//ConcreteState1的handle2会转接到ConcreteState2的handle2
context.handle2();
}
}
优点
结构清晰:避免过多的switch/case和if/else,提高系统的可维护性
遵循开闭原则和单一职责原则
封装性好,将状态的改变封装到State类的内部实现,外部不需要关心内部如何实现状态、行为的改变。
缺点
每一个状态一个类,如果状态太多会导致子类膨胀,不好管理
应用
行为随状态的改变而改变
switch/case的替代者
注意事项
状态最好不要超过5个