文章目录

  • 一、状态模式是什么?
  • 二、状态模式
  • 1.案例
  • 状态模式的优缺点
  • 优点
  • 缺点
  • 状态模式与策略模式的区别



一、状态模式是什么?

状态模式允许一个对象在其内部状态改变的时候改变其行为。这个对象看上去就像是改变了它的类一样。

二、状态模式

  • Context(环境类):环境类又称为上下文类,它是拥有多种状态的对象。由于环境类的状态存在多样性且在不同状态下对象的行为有所不同,因此将状态独立出去形成单独的状态类。
  • State(抽象状态类):它用于定义一个接口以封装与环境类的一个特定状态相关的行为,在抽象状态类中声明了各种不同状态对应的方法,而在其子类中实现类这些方法,由于不同状态下对象的行为可能不同,因此在不同子类中方法的实现可能存在不同,相同的方法可以写在抽象状态类中。
  • ConcreteState(具体状态类):它是抽象状态类的子类,每一个子类实现一个与环境类的一个状态相关的行为,每一个具体状态类对应环境的一个具体状态,不同的具体状态类其行为有所不同。

1.案例

  1. Context(环境类)
public class Context {

    //定义状态
    public final static State STATE1 = new ConcreteState1();
    public final static State STATE2 = new ConcreteState2();

    //当前状态
    private State state;


    //设置当前状态
    public void setCurrentState(State state) {
        this.state = state;
        //切换状态
        this.state.setContext(this);
    }

    public void handle1() {
        this.state.handle1();
    }
    public void handle2() {
        this.state.handle2();
    }
}
  1. State
public abstract  class State {
    protected Context context;
    public void setContext(Context context) {
        this.context = context;
    }

    public abstract void handle1();

    public abstract void handle2();
}
  1. ConcreteState
public class ConcreteState1 extends State {

    @Override
    public void handle1() {
        System.out.println("ConcreteState1 的 handle1 方法");
    }

    @Override
    public void handle2() {
        super.context.setCurrentState(Context.STATE2);
        System.out.println("ConcreteState1 的 handle2 方法");
    }

}

public class ConcreteState2  extends State{

    @Override
    public void handle1() {
        System.out.println("ConcreteState2 的 handle1 方法");
    }

    @Override
    public void handle2() {
        super.context.setCurrentState(Context.STATE2);
        System.out.println("ConcreteState2 的 handle2 方法");
    }
}
  1. 测试
public class Test {
    public static void main(String[] args) {
        //定义环境角色
        Context context = new Context();
        //初始化状态
        context.setCurrentState(new ConcreteState1());
        //行为执行
        context.handle1();
        context.handle2();
        System.out.println("===============================");
        //切换状态
        context.setCurrentState(new ConcreteState2());
        //行为执行
        context.handle1();
        context.handle2();
    }
}
  1. 结果

状态模式的优缺点

优点

  • 结构清晰,避免了过多的switch…case或if…else语句的使用
  • 很好的体现了开闭原则和单一职责原则,想要增加状态就增加子类,想要修改状态就修改子类即可
  • 封装性非常好,状态变化放置到了类的内部来实现,外部调用不需要知道类内部如何实现状态和行为的变换

缺点

  • 子类会太多,也即类膨胀

状态模式与策略模式的区别