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

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

相关推荐
时间静止不是简史4 小时前
生产事故排查:Redis 宕机导致补偿队列消费线程死亡,通话录音未上送业务平台
java·redis
2301_32241428047 小时前
基于SpringBoot+Vue的休闲零食超市管理系统的设计与实现59004-计算机毕设 原创(免费领源码+部署教程+开发环境)
java·vue.js·spring boot·redis·mysql·决策树·推荐算法
m0_敲代码的彭于晏1688 小时前
Vercel 前端部署与全栈开发实战指南
前端·状态模式
金銀銅鐵9 小时前
[Java] 用 GUI 展示 EnumSet 增减元素时的内部变化(上)
java·后端·ai编程
福建佰胜张工9 小时前
SMC 薄型气爪 MHF2-16D1 深度解析:平行开闭、低剖面结构在自动化装配中的选型与落地
java·服务器·安全·自动化
catoop10 小时前
API Key 设计与安全生成方案:结构拆解、数据库设计与 Java 实现
java·数据库·安全
system_error_x10 小时前
SpringBoot 集成 Thymeleaf 简洁入门
java·spring boot·后端
驭渊的小故事10 小时前
Spring AI Alibaba 实战:从maven依赖治理到声明式工具调用
java·人工智能·spring
Elastic 中国社区官方博客11 小时前
我们如何通过 70 多个拉取请求,将 OpenTelemetry Java agent 迁移到 invokedynamic
java·大数据·开发语言·elasticsearch·搜索引擎·全文检索·es
tyn18811 小时前
记录本地安装nacos服务的方法及异常
java·开发语言