“状态模式允许一个对象在其内部状态改变的时候改变其行为。这个对象看上去就像是改变了它的类一样。” –《JAVA与模式》
管理者持有多种状态,状态切换后,管理者调用Handle方法时,间接调用状态类中的Handle方法,从而根据当前状态的不同,就可以表现出不同的结果。
例如一个变形金刚,假设它有3中状态:汽车状态,人形状态,飞机状态。 不同的状态进行战斗的时候,采用的方式不同,分别是“撞击碾压”,“赤手空拳”和“导弹射击”。各个类及方法见下面类图
代码 State接口 public interface State { public void fight(); } CarState public class CarState implements State { private static String stateName ="汽车形态"; @Override public void fight() { System.out.println("横冲直撞碾压"); } @Override public String toString() { return stateName; } } FlightState public class FlightState implements State { private static String stateName ="飞机形态"; @Override public void fight() { System.out.println("发射导弹攻击"); } @Override public String toString() { return stateName; } } HumanState public class HumanState implements State { private static String stateName ="人性形态"; @Override public void fight() { System.out.println("赤手空拳搏斗"); } @Override public String toString() { return stateName; } } Transformer类 public class Transformer { private String name; private State currentState; public State transformTo(State state){ this.currentState=state; return this.currentState; } public void fight(){ this.currentState.fight(); } public Transformer(String name,State currentState) { this.name=name; this.currentState = currentState; } } 测试类 public class TransformerTest { public static void main(String[] args){ State currentState; //创建初始形态 State initState=new CarState(); //创建变形金刚 Transformer bumblebee= new Transformer("大黄蜂", initState); //开始战斗 bumblebee.fight(); //切换到人形形态 currentState= bumblebee.transformTo(new HumanState()); System.out.println("切换到:"+currentState); bumblebee.fight(); //切换到飞机形态 currentState= bumblebee.transformTo(new FlightState()); System.out.println("切换到:"+currentState); bumblebee.fight(); } } 输出结果 横冲直撞碾压 切换到:人性形态 赤手空拳搏斗 切换到:飞机形态 发射导弹攻击 Android源码中的使用举例Android系统源代码中有一个名为StateMachine的工具类,该类是一个分层状态机,处理各种State类的转化。State状态类必须实现processMessage方法,为了创建/摧毁工作环境,还可以继承实现enter/exit等方法。
相比较前面所说的基本的状态模式,StateMachine可以在每一个状态内,定义其接收不同的指令,会切换到哪个状态,而不需要状态机主动去设定状态,降低了主体和状态之间的耦合,增加一个新状态时更加方便。
状态机建立当一个StateMachine对象建立后,可以通过addState()函数来设定状态机有哪些状态,通过setInitialState()来设定初始的状态。通过start()方法来初始化并启动虚拟机。
addState(State state, State parent) ----state为当前增加的状态,parent为当前状态的父状态。状态机启动时首先调用初始State的enter函数来初始化当前状态,并且是从最顶层的父状态开始调用,然后再向下调用到子状态的enter。
mP1 / \ mS2 mS1 ----> initial state