少一点If/Else - 状态模式(State Pattern)

状态模式(State Pattern)

  • [状态模式(State Pattern)](#状态模式(State Pattern))
    • [状态模式(State Pattern)概述](#状态模式(State Pattern)概述)
      • [状态模式(State Pattern)结构图](#状态模式(State Pattern)结构图)
      • [状态模式(State Pattern)涉及的角色](#状态模式(State Pattern)涉及的角色)
    • [talk is cheap, show you my code](#talk is cheap, show you my code)
    • 总结

状态模式(State Pattern)

状态模式(State Pattern)是一种行为型设计模式,它允许对象在其内部状态改变时改变其行为。这个模式的核心思想是将对象的行为封装在不同的状态类中,每个状态类都实现了相同接口或继承自同一个抽象类。通过这种方式,当对象的状态发生变化时,它可以动态地更改其行为,避免了大量的条件分支语句(if-else 或 switch-case)。

属实有点抽象,还是举个现实中的例子

我们举一个H2O的例子,H2O是水的化学元素符号。但是水又有一个特点,在温度低于0摄氏度(标准大气压下面)的情况下,水是以固态的形式存在;温度在100摄氏度以上的时候以气态形式存在;在0摄氏度到100摄氏度之间的时候以液态形式存在。这个例子反应的就是我们本次要介绍的状态模式(State Pattern),即水这个对象在某一个状态转变的时候,以不同的形式存在。

状态模式(State Pattern)概述

状态模式(State Pattern)结构图

状态模式(State Pattern)涉及的角色

  1. 环境类(Context):环境类拥有对状态对象的引用,并且提供了客户端访问状态的方法。它还负责管理状态的变化。
java 复制代码
public class Context {
    private State state;

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

    public void setState(State state) {
        this.state = state;
        System.out.println("Current state set to " + state.getClass().getSimpleName());
    }

    public void request() {
        state.handle(this);
    }
}
  1. 抽象状态(State):这是一个接口或抽象类,声明了所有具体状态必须实现的方法。这些方法定义了不同状态下对象的行为。
java 复制代码
public interface State {
    void handle(Context context);
}
  1. 具体状态(ConcreteState):具体状态实现了State接口,每个具体状态类都包含了与该状态相关的行为逻辑。
java 复制代码
public class ConcreteStateA implements State {
    @Override
    public void handle(Context context) {
        System.out.println("Handling request in State A");
        // 改变状态
        context.setState(new ConcreteStateB());
    }
}

public class ConcreteStateB implements State {
    @Override
    public void handle(Context context) {
        System.out.println("Handling request in State B");
        // 改变状态
        context.setState(new ConcreteStateA());
    }
}

talk is cheap, show you my code

我们还是利用本次要介绍的状态设计模式来实现我们前面说的那个例子。

java 复制代码
// 抽象状态类
abstract class State {
    protected Water water;

    public State(Water water) {
        this.water = water;
    }

    public abstract void heat();
    public abstract void cool();
}

// 具体状态类:固态
class SolidState extends State {
    public SolidState(Water water) {
        super(water);
    }

    @Override
    public void heat() {
        System.out.println("Water is melting from solid to liquid.");
        water.setState(new LiquidState(water));
    }

    @Override
    public void cool() {
        System.out.println("Water is already in solid state. Cannot cool further.");
    }
}

// 具体状态类:液态
class LiquidState extends State {
    public LiquidState(Water water) {
        super(water);
    }

    @Override
    public void heat() {
        System.out.println("Water is evaporating from liquid to gas.");
        water.setState(new GasState(water));
    }

    @Override
    public void cool() {
        System.out.println("Water is freezing from liquid to solid.");
        water.setState(new SolidState(water));
    }
}

// 具体状态类:气态
class GasState extends State {
    public GasState(Water water) {
        super(water);
    }

    @Override
    public void heat() {
        System.out.println("Water is already in gas state. Cannot heat further.");
    }

    @Override
    public void cool() {
        System.out.println("Water is condensing from gas to liquid.");
        water.setState(new LiquidState(water));
    }
}

// 环境类:水
class Water {
    private State state;

    public Water() {
        state = new SolidState(this); // 假设初始状态为固态
    }

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

    public void heat() {
        state.heat();
    }

    public void cool() {
        state.cool();
    }

    public String getState() {
        return state.getClass().getSimpleName().replace("State", "");
    }
}

// 测试类
public class WaterStatePatternDemo {
    public static void main(String[] args) {
        Water water = new Water();

        System.out.println("Current state: " + water.getState());
        water.heat();
        System.out.println("Current state: " + water.getState());
        water.heat();
        System.out.println("Current state: " + water.getState());
        water.cool();
        System.out.println("Current state: " + water.getState());
        water.cool();
        System.out.println("Current state: " + water.getState());
    }
}

输出结果

java 复制代码
Current state: Solid
Water is melting from solid to liquid.
Current state: Liquid
Water is evaporating from liquid to gas.
Current state: Gas
Water is condensing from gas to liquid.
Current state: Liquid
Water is freezing from liquid to solid.
Current state: Solid

在这个例子中,Water类作为环境类持有一个State对象的引用,该对象表示水的当前状态。State是一个抽象类,定义了加热(heat)和冷却(cool)的方法。每种具体状态(固态、液态、气态)都实现了这些方法,并在方法内部包含了状态转换的逻辑。

总结

状态模式的优点

  • 简化对象的操作:状态模式将与特定状态相关的操作封装到状态类中,使得环境类可以专注于其他功能而不必处理复杂的状态逻辑。
  • 遵循开闭原则:新增加的状态只需要创建新的具体状态类,而不需要修改现有的代码,这符合面向对象设计中的开闭原则(Open/Closed Principle)。
  • 减少条件语句:通过将不同状态下的行为转移到相应的状态类中,减少了环境类中可能出现的大量条件判断语句。
  • 提高可读性和可维护性:每个状态都有自己的类,这有助于更好地组织代码,提高代码的可读性和可维护性。

状态模式主要应用在对象呈现出在不同状态显示出不一样的行为的时候。状态模式提供了一种有效的方式来解耦对象与其行为之间的关系,使得对象可以在不破坏封装的前提下,根据其内部状态的变化而改变行为。这对于构建具有复杂状态逻辑的应用程序特别有用。理解如何正确使用状态模式可以帮助开发者构建更加模块化、灵活且易于维护的软件系统。

相关推荐
留不住丨晚霞23 分钟前
说说SpringBoot常用的注解?
java·开发语言
华科云商xiao徐29 分钟前
Java多线程爬虫动态线程管理实现
java·爬虫·数据挖掘
柒七爱吃麻辣烫38 分钟前
八股文系列-----SpringBoot自动配置的流程
java·spring boot·rpc
M1A142 分钟前
Java 面试系列第一弹:基础问题大盘点
java·后端·mysql
发仔12343 分钟前
Dubbo介绍及示例用法
java·dubbo
goxingman1 小时前
关于使用idea打包的时候报错,Maven提示乱码java: �Ҳ�������
java·maven·intellij-idea
位东风2 小时前
【c++学习记录】状态模式,实现一个登陆功能
c++·学习·状态模式
邓不利东2 小时前
Spring中过滤器和拦截器的区别及具体实现
java·后端·spring
草履虫建模3 小时前
Redis:高性能内存数据库与缓存利器
java·数据库·spring boot·redis·分布式·mysql·缓存
苹果醋33 小时前
Vue3组合式API应用:状态共享与逻辑复用最佳实践
java·运维·spring boot·mysql·nginx