设计模式之状态模式

定义

允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。
类似于我们商城下单,订单有各种状态,不同的状态下可以执行不同的操作。

结构

  • State,状态接口,用来封装与上下文的一个特定状态所对应的行为。
  • ConcreteState,具体状态实现类,提供对应状态的具体行为处理。
  • Context,上下文,内部维护一个当前状态,并负责具体状态的切换。

简单实现

状态接口

public interface State {

  void handle(Context context);
}

具体状态实现类

public class ConcreteStateA implements State {

  @Override
  public void handle(Context context) {
    System.out.println("当前状态:A");
    //状态 A 执行完后,迁移到状态 B
    context.setState(new ConcreteStateB());
  }
}

另一个具体状态实现

public class ConcreteStateB implements State {

  @Override
  public void handle(Context context) {
    System.out.println("当前状态:B");
    //状态 B 执行完后,迁移到状态 A
    context.setState(new ConcreteStateA());
  }
}

上下文

public class Context {

  private State state;

  public Context(State state) {
    this.state = state;
  }

  public void handle() {
    // 注意:这里传入当前对象
    state.handle(this);
  }

  public State getState() {
    return state;
  }

  public Context setState(State state) {
    this.state = state;
    return this;
  }
}

客户端

public class Client {

  public static void main(String[] args) {
    Context context = new Context(new ConcreteStateA());
    context.handle();
    context.handle();
    context.handle();
    context.handle();
    context.handle();
  }

}

状态模式在JSF中的实现

JSF 是一种用于构建Java Web 应用程序的标准框架。

引入maven依赖

<dependency>
  <groupId>javax.faces</groupId>
  <artifactId>jsf-api</artifactId>
  <version>2.1</version>
  <scope>provided</scope>
</dependency>
<dependency>
  <groupId>com.sun.faces</groupId>
  <artifactId>jsf-impl</artifactId>
  <version>2.2.20</version>
</dependency>

示例

JSF中的FacesContext,PhaseId

public class PhaseId implements Comparable {
    ...
    private static final PhaseId[] values = {
        ANY_PHASE,    // 任意一个生命周期阶段
        RESTORE_VIEW,    // 恢复视图阶段
        APPLY_REQUEST_VALUES,    // 应用请求值阶段
        PROCESS_VALIDATIONS,    // 处理输入校验阶段
        UPDATE_MODEL_VALUES,    // 更新模型的值阶段
        INVOKE_APPLICATION,    // 调用应用阶段
        RENDER_RESPONSE    // 显示响应阶段
    };
    ...
}

FacesContext中保存一个阶段对象

public class FacesContextImpl extends FacesContext {

    private PhaseId currentPhaseId;

}

总结

优点

  1. 简化应用逻辑控制,使用单独的类来封装一个状态的处理,分离了状态和行为的处理。
  2. 更好的扩展性,很容易新增状态类的实现。

缺点

  1. 一个状态对应一个状态处理类,会导致类的数量过多,程序复杂。

本质

状态模式的本质是根据状态来分离和选择行为,通过接口分离了状态和行为,通过上下文来选择行为。

使用场景

  1. 一个对象的行为取决于它的状态,并且必须在运行时根据状态来改变它的行为。
  2. 一个操作中包含大量的分支语句,且这些分支依赖于该对象的状态,可以将各分支的处理封装到单独的状态处理类中。

参考

大战设计模式【14】—— 状态模式
设计模式——状态模式
状态模式(详解版)
设计模式(二十二)——状态模式(APP抽奖活动+借贷平台源码剖析)
研磨设计模式-书籍

posted @ 2021-09-06 21:00  strongmore  阅读(58)  评论(0编辑  收藏  举报