<<设计模式之禅(第二版)>>——第二十六章 状态模式

定义:
  • 当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类。(状态模式的核心是封装,状态的变更引起了行为的变更,从外部看起来就好像这个对象对应的类发生了改变一样。)
<<设计模式之禅(第二版)>>——第二十六章 状态模式_第1张图片
状态模式通用类图

State——接口或者抽象类,负责对象状态的定义,并且封装环境角色以实现状态切换
ConcreteState——每一个具体状态角色必须完成两个职责,本状态的行为管理以及趋向状态管理(即如何过渡到下一个状态)
Context——定义客户端需要的接口,并且负责具体的切换

public abstract class State {
  // 定义一个环境角色,提供子类进行访问
  /*
   * 抽象环境中声明一个环境角色,
   * 提供各个状态类 自行访问,
   * 同时提供所有状态的抽象行为,
   * 由各个实现类实现
   */
  protected Context context;
  public void setContext(Context _context){
    this.context = _context;
  }
  //行为1
  public abstract void handle1();
  //行为2
  public abstract void handle2();   
}
public class ConcreteStateOne extends State {

  @Override
  public void handle1() {
    // TODO Auto-generated method stub
    // 自身状态下必须处理的逻辑
  }

  @Override
  public void handle2() {
    // TODO Auto-generated method stub
    //更改当前的状态为状态2
    super.context.setCurrContext(Context.STATE2);
    //过渡到state2,由Context实现
    super.context.handle2();
  }

}
public class ConcreteStateTwo extends State {

  @Override
  public void handle1() {
    // TODO Auto-generated method stub
    // 通过Context进行状态的改变,并采取相应的行为
    super.context.setCurrContext(Context.STATE1);
    super.context.handle1();
  }

  @Override
  public void handle2() {
    // TODO Auto-generated method stub
    // 自身状态的逻辑处理

  }

}

public class Context {
  /*
   * 环境角色不成文约束:
   * 1、把状态对象声明为静态常量,有几个状态对象就声明几个静态常量
   * 2、环境角色具有状态抽象角色定义的所有行为,具体执行使用委托方式
   */
  public static final State STATE2 = new ConcreteStateTwo();
  public static final State STATE1 = new ConcreteStateOne();

  // 定义当前的状态
  private State mCurrState;

  public void setCurrContext(State state) {
    // TODO Auto-generated method stub
    this.mCurrState = state;
    // 切换状态,使用此context封装当前状态
    this.mCurrState.setContext(this);
  }

  // 行为委托
  public void handle2() {
    // TODO Auto-generated method stub
    this.mCurrState.handle2();
  }

  public void handle1() {
    // TODO Auto-generated method stub
    this.mCurrState.handle1();
  }

}
public class Client {
    public static void main(String[] args) {
    Context context = new Context();

    context.setCurrContext(new ConcreteStateOne());
    context.handle1();
    context.handle2();
    /*我们已经隐藏了状态的变化过程,
     * 它的切换引起了行为的切换,
     * 对我们来说我们只看到了行为的切换,
     * 而不用知道是状态变化引起的 */
  }
}
优点:
  • 结构清晰,避免了过多的switch...case 或者 if...else 语句的使用,避免了程序的复杂性,提高系统的可维护性
  • 遵循设计原则,很好的体现了开闭原则和单一职责原则,每个状态都是一个子类,你要增加状态就要增加子类,修改状态,修改对应的子类即可
  • 封装性非常好,状态变化放到类的内部来实现,外部的调用不用知道类内部如何实现状态和行为的变化
缺点:
  • 子类会太多,引起类膨胀
使用场景:
  • 行为随状态改变而改变的场景,如人员的状态不同即使执行相同的行为,结果也会不同
  • 条件、分支判断语句替代者,在程序中大量使用switch语句或者if语句会导致程序结构不清晰,逻辑混乱,使用状态模式可以很好地避免这一问题,他通过拓展子类实现了条件的判断处理。

你可能感兴趣的:(<<设计模式之禅(第二版)>>——第二十六章 状态模式)