首先直观对比一下两种模式,左图:状态模式;右图:策略模式。可以看出,状态模式是在策略模式的基础上,增加了状态类对环境类的“反向调用”。
状态模式(State)定义:对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。
状态模式的优点有:
1、状态模式将与特定状态相关的行为局部化到一个状态中,并且将不同状态的行为分割开来,满足“单一职责原则”。
2、减少对象间的相互依赖。将不同的状态引入独立的对象中会使得状态转换变得更加明确,且减少对象间的相互依赖。
3、有利于程序的扩展。通过定义新的子类很容易地增加新的状态和转换。
状态类:
1 public abstract class State { 2 public abstract void Handle(Context context); 3 } 4 5 public class ConcreteStateA extends State { 6 @Override 7 public void Handle(Context context) { 8 // TODO Auto-generated method stub 9 System.out.println("当前状态是A,已转移到状态B"); 10 // 切换到状态B 11 context.setState(new ConcreteStateB()); 12 } 13 } 14 15 public class ConcreteStateB extends State { 16 @Override 17 public void Handle(Context context) { 18 // TODO Auto-generated method stub 19 System.out.println("当前状态是B,已转移到状态A"); 20 //切换到状态A 21 context.setState(new ConcreteStateA()); 22 } 23 }
环境类:
1 public class Context { 2 private State state; 3 4 public Context() { 5 //默认状态 6 this.state = new ConcreteStateA(); 7 } 8 9 public State getState() { 10 return state; 11 } 12 13 public void setState(State state) { 14 this.state = state; 15 } 16 17 public void Handle() { 18 state.Handle(this); 19 } 20 }
调用方式:
1 public class Client { 2 /* 3 * 当控制一个对象状态转换的条件表达式过于复杂时, 4 * 把相关“判断逻辑”提取出来, 放到一系列的状态类当中, 5 * 这样可以把原来复杂的逻辑判断简单化。 6 */ 7 public static void main(String[] args) { 8 // TODO Auto-generated method stub 9 //可以先画一个"状态转移图",根据图形设定"状态类"和"转移条件" 10 Context context = new Context(); 11 12 //经过t个时间(所达到的状态) 13 for (int t = 0; t < 4; t++) { 14 context.Handle(); 15 } 16 } 17 }
执行结果:
状态模式是有向图数据结构的体现。