学习设计模式之状态模式

状态模式
当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

上面是百度百科的解释,看起来有点难以理解其实可以理解为:它说当状态改变时,这个对象的行为也会变,而看起来就像是这个类改变了一样。

类结构图

在这里插入图片描述
Context
含有状态的类,维护一个 State 的实例。
State
状态接口。抽象状态类,定义一个接口以封装与 Context 的的一个状态相关的行为。
ConcreteState
具体的状态类。

代码示例

public interface State {
    void handle();
}

public class ConcreteStateA implements State {
    @Override
    public void handle() {
        System.out.println("State 状态 A 的处理逻辑!");
    }
}

public class ConcreteStateB implements State {
    @Override
    public void handle() {
        System.out.println("State 状态 B 的处理逻辑!");
    }
}

public class Context {
    public static final State STATE_A = new ConcreteStateA();

    public static final State STATE_B = new ConcreteStateB();

    private State state = STATE_A;

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

    public void execute() {
        this.state.handle();
    }
}

客户端示例

public class Client {
    public static void main(String[] args) {
        // 默认状态 A
        Context context = new Context();
        context.execute();
        // 切换为状态 B
        context.setState(Context.STATE_B);
        context.execute();
        // 再切换为状态 A
        context.setState(Context.STATE_A);
        context.execute();
    }
}

运行结果

Connected to the target VM, address: '127.0.0.1:58526', transport: 'socket'
State 状态 A 的处理逻辑!
State 状态 B 的处理逻辑!
State 状态 A 的处理逻辑!
Disconnected from the target VM, address: '127.0.0.1:58526', transport: 'socket'

Process finished with exit code 0

什么时候考虑使用状态模式?
当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式了。
如果某项业务有多个状态,通常是一些枚举、常量,状态的变化都是靠大量 if 分支判断语句来实现,此时应该考虑将业务状态定义为一个 State 的子类。

优点
将与特定状态相关的行为局部化,并且将不同的状态的行为分割开来。

缺点

  1. 状态模式的使用必然会增加系统类和对象的个数。
  2. 状态模式对“开闭原则”的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态;而且修改某个状态类的行为也需修改对应类的源代码。
勿在浮沙筑高台 ——个人浅见,难免有误导之处,麻烦请指出。
原文地址:https://www.cnblogs.com/liufeichn/p/11961644.html