状态模式(行为设计模式)
让你能在一个对象的内部状态变化时改变其行为, 使其看上去就像改变了自身所属的类一样。
主要思想是程序在任意时刻仅可处于几种有限的状态中。 在任何一个特定状态中, 程序的行为都不相同, 且可瞬间从一个状态切换到另一个状态。 不过, 根据当前状态, 程序可能会切换到另外一种状态, 也可能会保持当前状态不变。 这些数量有限且预先定义的状态切换规则被称为转移。
状态机通常由众多条件运算符 ( if或 switch ) 实现, 可根据对象的当前状态选择相应的行为。 “状态” 通常只是对象中的一组成员变量值。
例子
public interface State {
public void action(Context context);
}
public class StartState implements State {
public void action(Context context){
System.out.println("Player is in start state");
context.setState(this);
}
}
public class Context {
private State state;
public Context() {
state = null;
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
}
public class ClientDemo {
public static void main(String[] args) {
Context context = new Context();
StartState startState = new StartState();
startState.action(context);
System.out.println(context.getState().getClass());
stopState stopState = new stopState();
stopState.action(context);
System.out.println(context.getState().getClass());
}
}
总结
- 优点:
1、封装了转换规则。
2、枚举可能的状态,在枚举状态之前需要确定状态种类。
3、将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。
4、允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。
5、可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。 - 缺点:
1、状态模式的使用必然会增加系统类和对象的个数。 ==
2、状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。
3、状态模式对"开闭原则"的支持并不太好==,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码。 - 使用场景:
1、行为随状态改变而改变的场景。
2、条件、分支语句的代替者。 - 注意事项:在行为受状态约束的时候使用状态模式,而且状态不超过 5 个。