面向对象设计其实就是希望做到代码的责任分解。
状态模式(State),当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了它的类一样。
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
State类,抽象状态类,定义一个接口以封装与Context的一个特定状态相关的行为。
public abstract class State {
public abstract void handle(Context context);
}
ConcreteState类,具体状态,每一个子类实现一个与Context的一个状态相关的行为。
变形金刚根据不同的时间,有不同的状态。
public class CarState extends State {
@Override
public void handle(Context context) {
if (context.getHour() < 12 ) {
System.out.println("汽车人状态,撞击碾压");
} else {
context.setState(new FlightState());
context.request();
}
}
}
public class FlightState extends State {
@Override
public void handle(Context context) {
if (context.getHour() < 18) {
System.out.println("飞机状态,发射导弹攻击");
} else {
context.setState(new HumanState());
context.request();
}
}
}
public class HumanState extends State {
@Override
public void handle(Context context) {
System.out.println("人状态,睡觉。。。");
}
}
Context类,维护一个ConcreteState子类的实例,这个实例定义当前的状态。
public class Context {
private State mCurrentState;
private int mHour;
public Context() {
mCurrentState = new CarState();
}
public void setState(State state) {
mCurrentState = state;
}
public void setHour(int hour) {
mHour = hour;
}
public int getHour() {
return mHour;
}
public void request() {
mCurrentState.handle(this);
}
}
调用:
Context context = new Context();
context.setHour(10);
context.request();
context.setHour(13);
context.request();
context.setHour(20);
context.request();
输出结果:
汽车人状态,撞击碾压
飞机状态,发射导弹攻击
人状态,睡觉。。。
状态模式的好处:
将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在于某个ConcreteState中,所以通过定义新的子类可以很容易地增加新的状态和转换。
消除庞大的条件分支语句。
状态模式通过把各种状态转移逻辑分布到State的子类之间,来减少相互间的依赖。
当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式。