少一点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)。
  • 减少条件语句:通过将不同状态下的行为转移到相应的状态类中,减少了环境类中可能出现的大量条件判断语句。
  • 提高可读性和可维护性:每个状态都有自己的类,这有助于更好地组织代码,提高代码的可读性和可维护性。

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

相关推荐
bing_15821 分钟前
Spring Boot Actuator 详细介绍
java·spring boot·后端
带多刺的玫瑰29 分钟前
Leecode刷题C语言之或值至少K的最短子数组①
java·c语言·算法
cdut_suye32 分钟前
冯·诺依曼体系结构:计算机科学的奠基石
java·linux·c++·人工智能·python·ubuntu·机器学习
心 -33 分钟前
七大排序算法
java·算法·排序算法
想要飞翔的企鹅37 分钟前
Notepad++移除所有空格
java·数据库·notepad++
半旧5181 小时前
cursor重构谷粒商城02——30分钟构建图书管理系统【cursor使用教程番外篇】
java·重构·全栈·cursor·谷粒商城·全栈项目
Future_yzx1 小时前
1️⃣Java中的集合体系学习汇总(List/Map/Set 详解)
java·学习·list
GeekyGuru1 小时前
Java 面试题 - ArrayList 和 LinkedList 的区别,哪个集合是线程安全的?
java·开发语言
多多*1 小时前
双端队列实战 实现滑动窗口 用LinkedList的基类双端队列Deque实现 洛谷[P1886]
java·开发语言·jvm·数据结构·redis·算法
迷迷的k1 小时前
使用 Docker 部署 Java 项目(通俗易懂)
java·docker·项目部署