状态模式(行为设计模式)

让你能在一个对象的内部状态变化时改变其行为, 使其看上去就像改变了自身所属的类一样。

主要思想是程序在任意时刻仅可处于几种有限的状态中。 在任何一个特定状态中, 程序的行为都不相同, 且可瞬间从一个状态切换到另一个状态。 不过, 根据当前状态, 程序可能会切换到另外一种状态, 也可能会保持当前状态不变。 这些数量有限且预先定义的状态切换规则被称为转移。

状态机通常由众多条件运算符 ( if或 switch ) 实现, 可根据对象的当前状态选择相应的行为。 “状态” 通常只是对象中的一组成员变量值。

经典状态机软件架构 状态机设计模式 实例_设计模式

例子

经典状态机软件架构 状态机设计模式 实例_程序结构_02

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 个