状态模式:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
类图:
Context是一个类,它可以拥有一些内部状态。
State接口定义了一个所有具体状态的共同接口,任何状态都实现这个相同的接口,这样一来,状态之间可以互相替换。
ConcreteState(具体状态)处理来自Context的请求。每一个ConcreteState都提供了它自己对于请求的实现。所以,当Context改变状态时行为也跟着改变。
Context类代码实现:
public class Context {
State stateA;
State stateB;
State state;
public Context(){
stateA = new ConcreteStateA(this);
stateB = new ConcreteStateB(this);
state = stateA;
}
public void request(){
state.handle();
}
public void setState(State state){
this.state = state;
}
}
抽象类State代码实现:
public abstract class State {
Context context;
public State(Context context){
this.context = context;
}
public abstract void handle();
}
ConcreteStateA类代码实现:
public class ConcreteStateA extends State{
public ConcreteStateA(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
@Override
public void handle() {
// TODO Auto-generated method stub
context.setState(context.stateB);
System.out.println("stateA to stateB");
}
}
ConcreteStateB类代码实现:
public class ConcreteStateB extends State{
public ConcreteStateB(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
@Override
public void handle() {
// TODO Auto-generated method stub
context.setState(context.stateA);
System.out.println("stateB to stateA");
}
}
测试类stateTest代码实现:
public class stateTest {
public static void main(String[] args){
Context context = new Context();
//stateA to stateB
context.request();
//stateB to stateA
context.request();
}
}
运行结果:
stateA to stateB
stateB to stateA
总结:
状态模式允许一个对象基于内部状态而拥有不同的行为。
和程序状态机(PSM)不同,状态模式用类代表状态。
Context会将行为委托给当前状态对象。
通过将每个状态封装进一个类,我们把以后需要做的任何改变局部化了。
状态模式和策略模式有相同的类图,但是它们的意图不同。
状态模式允许Context随着状态的改变而改变行为。
状态转换可以由State类或Context类控制。
使用状态模式通常会导致设计中类的数目大量增加。
状态类可以被多个Context实例共享。