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

状态模式(State Pattern)

  • 状态模式(State Pattern)
    • 状态模式(State Pattern)概述
      • 状态模式(State Pattern)结构图
      • 状态模式(State Pattern)涉及的角色
    • 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):环境类拥有对状态对象的引用,并且提供了客户端访问状态的方法。它还负责管理状态的变化。
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):这是一个接口或抽象类,声明了所有具体状态必须实现的方法。这些方法定义了不同状态下对象的行为。
public interface State {void handle(Context context);
}
  1. 具体状态(ConcreteState):具体状态实现了State接口,每个具体状态类都包含了与该状态相关的行为逻辑。
public class ConcreteStateA implements State {@Overridepublic void handle(Context context) {System.out.println("Handling request in State A");// 改变状态context.setState(new ConcreteStateB());}
}public class ConcreteStateB implements State {@Overridepublic void handle(Context context) {System.out.println("Handling request in State B");// 改变状态context.setState(new ConcreteStateA());}
}

talk is cheap, show you my code

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

// 抽象状态类
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);}@Overridepublic void heat() {System.out.println("Water is melting from solid to liquid.");water.setState(new LiquidState(water));}@Overridepublic void cool() {System.out.println("Water is already in solid state. Cannot cool further.");}
}// 具体状态类:液态
class LiquidState extends State {public LiquidState(Water water) {super(water);}@Overridepublic void heat() {System.out.println("Water is evaporating from liquid to gas.");water.setState(new GasState(water));}@Overridepublic 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);}@Overridepublic void heat() {System.out.println("Water is already in gas state. Cannot heat further.");}@Overridepublic 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());}
}

输出结果

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/2281.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mayavi -> python 3D可视化工具Mayavi的安装

前言 Mayavi是一个基于VTK(Visualization Toolkit)的科学计算和可视化工具,主要用于数据可视化和科学计算领域。 它提供了一系列的高级可视化工具,包括2D和3D图形、表面和体积渲染、流场可视化等。Mayavi可以通过Python脚本进行调…

idea 自动导包,并且禁止自动导 *(java.io.*)

自动导包配置 进入 idea 设置,可以按下图所示寻找位置,也可以直接输入 auto import 快速定位到配置。 Add unambiguous imports on the fly:自动帮我们优化导入的包Optimize imports on the fly:自动去掉一些没有用到的包 禁止导…

BI 是如何数据分析的?

企业部署商业智能BI前,需要进行详细的分析,了解BI能为企业带来多少价值?如何提高工作效率的等等,今天我们就来聊一聊 BI 的工作原理。 一、BI的取数方式 商业智能BI是通过访问和连接业务系统数据源数据库的方式来进行取数的&…

宇泰串口卡驱动在Ubuntu22.04编译、安装汇总

从官网下载驱动官网地址 上传到Ubuntu, 目录结构如下: 驱动源代码: 驱动代码是基于开源项目编译来的 编译路径不能有中文路径,否则可能有类似错误 源码是基于Linux2.3内核编译,我当前是6.8.0-51,数据结构有升级,需要调…

HarmonyOS 鸿蒙 ArkTs(5.0.1 13)实现Scroll下拉到顶刷新/上拉触底加载,Scroll滚动到顶部

HarmonyOS 鸿蒙 ArkTs(5.0.1 13)实现Scroll下拉到顶刷新/上拉触底加载 效果展示 使用方法 import LoadingText from "../components/LoadingText" import PageToRefresh from "../components/PageToRefresh" import FooterBar from "../components/…

上传自己的镜像到docker hub详细教程

上传自己的镜像到docker hub详细教程 本博客通B站视频一致: 上传自己的镜像到docker hub详细教程 1. 登录自己的hub.docker.com的账号 docker hub仓库 2. 点击Repositories,跳转到创建仓库页面 3. 点击Create a repository 创建repository&#xff0c…

[AI部署-tensorRT] customlayer定义添加过程解析

文章目录 tensorRT添加自定义层步骤1. trt如何解析onnx的? 整体流程图2. builtin_op_importor是干什么的?3. 怎么添加trt plugin4. 如何进行量化collection过程 references nvidia 官方plugin文档: https://www.nvidia.cn/content/dam/en-zz/…

[Do374]Ansible一键搭建sftp实现用户批量增删

[Do374]Ansible一键搭建sftp实现用户批量增删 1. 前言2. 思路3. sftp搭建及用户批量新增3.1 配置文件内容3.2 执行测试3.3 登录测试3.4 确认sftp服务器配置文件 4. 测试删除用户 1. 前言 最近准备搞一下RHCA LV V,外加2.9之后的ansible有较大变化于是练习下Do374的课程内容. 工…

易语言文字识别OCR

一.引言 文字识别,也称为光学字符识别(Optical Character Recognition, OCR),是一种将不同形式的文档(如扫描的纸质文档、PDF文件或数字相机拍摄的图片)中的文字转换成可编辑和可搜索的数据的技术。随着技…

Docker 镜像制作原理 做一个自己的docker镜像

一.手动制作镜像 启动容器进入容器定制基于容器生成镜像 1.启动容器 启动容器之前我们首先要有一个镜像,这个镜像可以是从docker拉取,例如:现在pull一个ubuntu镜像到本机。 docker pull ubuntu:22.04 我们接下来可以基于这个容器进行容器…

网络编程 - - TCP套接字通信及编程实现

概述 TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的传输层协议。在网络编程中,TCP常用于实现客户端和服务器之间的可靠数据传输。本文将基于C语言实现TCP服务端和客户端建立通信的过程。 三次握手 在…

近红外简单ROI分析matlab(NIRS_SPM)

本次笔记主要想验证上篇近红外分析是否正确,因为叠加平均有不同的计算方法,一种是直接将每个通道的5分钟实时长单独进行叠加平均,另一种是将通道划分为1分钟的片段,将感兴趣的通道数据进行对应叠加平均,得到一个总平均…

从玩具到工业控制--51单片机的跨界传奇【2】

咱们在上一篇博客里面讲解了什么是单片机《单片机入门》,让大家对单片机有了初步的了解。我们今天继续讲解一些有关单片机的知识,顺便也讲解一下我们单片机用到的C语言知识。如果你对C语言还不太了解的话,可以看看博主的C语言专栏哟&#xff…

Python调用go语言编译的库

要在 Python 中调用用 Go 语言编写的库,可以使用 Go 语言的 cgo 特性将 Go 代码编译成共享库(如 .so 文件),然后在 Python 中通过 ctypes 或 cffi 模块加载和调用这个共享库。 新建main.go文件,使用go语言编写如下代码…

学成在线_内容管理模块_创建模块工程

学成在线模块工程 1.各个微服务依赖基础工程2.每个微服务都是一个前后端分离的项目3.xuecheng-plus-content:内容管理模块工程xuecheng-plus-content-modelxuecheng-plus-content-servicexuecheng-plus-content-api 1.各个微服务依赖基础工程 2.每个微服务都是一个前…

1️⃣Java中的集合体系学习汇总(List/Map/Set 详解)

目录 01. Java中的集合体系 02. 单列集合体系​ 1. Collection系列集合的遍历方式 (1)迭代器遍历(2)增强for遍历​编辑(3)Lambda表达式遍历 03.List集合详解 04.Set集合详解 05.总结 Collection系列…

智能科技与共情能力加持,哈曼重新定义驾乘体验

2025年1月6日,拉斯维加斯,2025年国际消费电子展——想象一下,当您步入一辆汽车,它不仅能响应您的指令,更能理解您的需求、适应您的偏好,并为您创造一个独特且专属的交互环境。作为汽车科技领域的知名企业和…

Unity中实现倒计时结束后干一些事情

问题描述:如果我们想实现在一个倒计时结束后可以执行某个方法,比如挑战成功或者挑战失败,或者其他什么的比如生成boss之类的功能,而且你又不想每次都把代码复制一遍,那么就可以用下面这种方法。 结构 实现步骤 创建一…

从0开始学习搭网站第二天

前言:今天比较惭愧,中午打铲吃了一把,看着也到钻二了,干脆顺手把这个赛季的大师上了,于是乎一直到网上才开始工作,同样,今天的学习内容大多来自mdn社区mdn 目录 怎么把文件上传到web服务器采用S…

STM32 FreeRTOS时间片调度---FreeRTOS任务相关API函数---FreeRTOS时间管理

目录 时间片调度简介 FreeRTOS任务相关API函数介绍 延时函数介绍 时间片调度简介 在FreeRTOS中,同等优先级的任务会轮流分享相同的CPU时间,这个时间被称为时间片。在这里,一个时间片的长度等同于SysTick中断的周期。 FreeRTOS任务相关API…