当前位置: 首页 > news >正文

【设计模式-状态模式】

状态模式(State Pattern)是一种行为设计模式,它允许一个对象在内部状态改变时改变它的行为。换句话说,这种模式让对象在不同的状态下能够表现出不同的行为,而不需要修改对象的代码。状态模式通过将对象的行为与状态进行解耦,使得状态的变化变得更容易管理和扩展。

1. 状态模式的基本概念

状态模式的核心思想是:将特定状态下的行为封装到状态类中,主对象的行为取决于它所处的状态。在状态模式中,通常会包含以下几个关键角色:

  • Context(上下文): 这是拥有状态的对象。它维护当前状态的实例,并且会根据状态变化来委托行为的执行。上下文对象通常会暴露改变状态的方法。
  • State(状态接口/抽象类): 这是一个接口或抽象类,定义了所有状态的公共行为。不同的状态类实现这个接口来定义具体的行为。
  • ConcreteState(具体状态): 这是实现状态接口的类,每个类表示对象的一个具体状态。它们实现接口中定义的行为,并且可以通过改变上下文中的状态来切换行为。

2. 状态模式的UML 图

状态模式的结构图通常包括Context和多个实现了State接口的具体状态类。如下所示:

在这里插入图片描述

3. 状态模式的工作原理

状态模式的关键在于将状态从主对象(上下文)中分离出来。上下文对象拥有一个状态的引用,并且在调用某个方法时,将方法的调用委托给当前状态。这就意味着,每次调用时的具体行为取决于当前的状态实例。

4. 代码示例

以下是一个使用状态模式的简单代码示例:假设一个订单系统的状态有三种——新订单、已支付和已发货,我们使用状态模式来表示这些不同状态下的行为。

// State 接口
interface OrderState {void handleOrder();
}// 具体状态:新订单
class NewOrderState implements OrderState {@Overridepublic void handleOrder() {System.out.println("处理新订单:等待支付。");}
}// 具体状态:已支付
class PaidOrderState implements OrderState {@Overridepublic void handleOrder() {System.out.println("订单已支付:准备发货。");}
}// 具体状态:已发货
class ShippedOrderState implements OrderState {@Overridepublic void handleOrder() {System.out.println("订单已发货:等待收货。");}
}// Context 类:订单
class Order {private OrderState state;// 设置初始状态public Order(OrderState state) {this.state = state;}// 更改订单状态public void setState(OrderState state) {this.state = state;}// 处理订单public void processOrder() {state.handleOrder();}
}// 使用状态模式的例子
public class StatePatternDemo {public static void main(String[] args) {// 创建订单并设置初始状态为新订单Order order = new Order(new NewOrderState());order.processOrder(); // 输出:处理新订单:等待支付。// 更改状态为已支付order.setState(new PaidOrderState());order.processOrder(); // 输出:订单已支付:准备发货。// 更改状态为已发货order.setState(new ShippedOrderState());order.processOrder(); // 输出:订单已发货:等待收货。}
}

5. 状态模式的优缺点

优点:
  • 封装状态转换逻辑: 状态模式将状态相关的行为封装在不同的状态类中,使得代码更加清晰、易于理解。
  • 易于扩展: 新增状态只需添加新的状态类,不会影响现有代码,符合开闭原则。
  • 减少条件判断: 消除了大量的if-elseswitch-case语句,避免了复杂的条件判断。
缺点:
  • 类数量增多: 每个具体状态都是一个类,可能会导致类的数量增加,增加了系统的复杂性。
  • 状态转换的管理可能复杂: 如果状态之间的转换非常复杂,可能会导致状态的管理逻辑变得难以维护。

6. 使用场景

状态模式通常在以下场景下使用:

  • 对象的行为依赖于它的状态,并且它在运行时会根据状态改变行为。
  • 代码中包含大量与状态相关的条件判断语句,这些条件判断的变化频率较高。
  • 需要根据状态切换来改变对象的行为而不希望直接修改类的代码。

通过状态模式,可以使状态转换更加清晰明了,提高代码的可维护性和可扩展性。

相关文章:

【设计模式-状态模式】

状态模式(State Pattern)是一种行为设计模式,它允许一个对象在内部状态改变时改变它的行为。换句话说,这种模式让对象在不同的状态下能够表现出不同的行为,而不需要修改对象的代码。状态模式通过将对象的行为与状态进行…...

【代码随想录Day50】图论Part02

岛屿数量 深搜 题目链接/文章讲解&#xff1a;代码随想录 class Solution {// 计算网格中岛屿的数量public int numIslands(char[][] grid) {int sum 0; // 初始化岛屿数量为0// 遍历整个网格for (int i 0; i < grid.length; i) {for (int j 0; j < grid[0].length…...

帝国CMS 内容页调用上一篇下一篇的方法(精华汇总)

帝国cms默认的内容页的上一页&下一页的调用代码是&#xff1a; 上一篇&#xff1a;[!--info.pre--] 下一篇&#xff1a;[!--info.next--] 但是实话实说&#xff0c;如果做个很普通的模版那足够用了&#xff0c;但是如果想个性化一点的话&#xff0c;比如加背景&#xff…...

(7)c++复合数据类型之数组

数组 数组就是可以存储一组相同类型的值&#xff0c;比如int a[10];就是一个存储10个int类型的数组。 数组初始化 数组初始化可以单个初始化&#xff0c;也是使用列表初始化&#xff0c;列表初始化可以全部&#xff0c;或者部分&#xff0c;如下案例&#xff1a; #include &…...

2.1 > Shell 是什么、如何更熟练的使用 Bash Shell

Shell 基础知识 Shell是计算机操作系统中的一个命令行解释器&#xff0c;由C语言编写&#xff0c;用于用户与操作系统之间进行交互。用户可以通过Shell输入命令&#xff0c;操作系统接收到这些命令后执行相应的操作。Shell一般还提供了编程语言的基本功能&#xff0c;允许用户…...

YOLO V3 网络构架解析

YOLO V3&#xff08;You Only Look Once version 3&#xff09;是由Joseph Redmon等人于2018年提出的一种基于深度学习的目标检测算法。它在速度和精度上相较于之前的版本有了显著提升&#xff0c;成为计算机视觉领域的一个重要里程碑。本文将详细解析YOLO V3的网络架构&#x…...

【zlm】 webrtc源码讲解(二)

目录 webrtc播放 MultiMediaSourceMuxer里的_ring webrtc播放 > MediaServer.exe!mediakit::WebRtcPlayer::onStartWebRTC() 行 60 CMediaServer.exe!mediakit::WebRtcTransport::OnDtlsTransportConnected(const RTC::DtlsTransport * dtlsTransport, RTC::SrtpSession::…...

5G RedCap工业路由器赋能电力物联网应用

随着5G轻量化技术应用的推进&#xff0c;5G RedCap旨在提供低功耗、低成本、广覆盖等功能特点赋能电力智能化升级。特别适用于工业物联网、低空经济、车联网、消费电子和轻量级5G的需求。 5G RedCap工业路由器的特点 低功耗&#xff1a;5G RedCap工业路由器通过节能技术&#…...

029.浏览器自动化-抓取#document下的内容

一、iframe下的#document是什么 #document 是一个特殊的 HTML 元素&#xff0c;表示 <iframe> 元素内部的文档对象。当你在 HTML 页面中嵌入一个 <iframe> 元素时&#xff0c;浏览器会创建一个新的文档对象来表示 <iframe> 内部的内容。这 个文档对象就是 #…...

2024前端html5,css3面试题总汇

1.XML&#xff0c;HTML&#xff0c;XHTML区别⭐ XML&#xff1a;XML是一个可扩展标记语言&#xff0c;主要是用来存储&#xff0c;传输数据的&#xff0c;并非显示数据&#xff0c;可以用来标记数据&#xff0c;定义数据类型&#xff0c;允许用户对自己的标记语言进行定义&…...

css实现外层不换行,内层换行

css实现上图效果&#xff0c;内容A和B整体不换行&#xff0c;B内容中换行 <div className"description"> <div className"label">{formatMessage({id: description})}</Col> <divclassName"value"> &l…...

word取消自动单词首字母大写

情况说明&#xff1a;在word输入单词后首字母会自动变成大写 &#xff08;1&#xff09;点击菜单栏文件 &#xff08;2&#xff09;点击“更多”——>“选项” &#xff08;3&#xff09;点击“校对”——>“自动更正选项” &#xff08;4&#xff09;取消“句首字母大写…...

flex常用固定搭配

flex常用固定搭配 flex简写&#xff1a;flex-grow&#xff08;项目放大&#xff09;&#xff0c;flex-shrink &#xff08;项目缩小&#xff09;&#xff0c;flex-basis&#xff08;项目本身&#xff09; flex: 1; 全写&#xff1a;flex: 1 1 0%;内容自动放大或缩小占满剩余…...

Kafka、Kafka Streams、Drools、Redis 和分布式数据库的风控系统程序

由于实时风控系统难度较大&#xff0c;集成框架设计各个单位均有特点&#xff0c;快速建立一个通用性较强&#xff0c;学习、实施和使用成本较低的框架尤其重要。 提供一个简化的 Java 程序示例&#xff0c;演示如何将 Kafka 消息中间件、Kafka Streams 计算引擎、Drools 规则…...

C++在实际项目中的应用第一课:游戏开发中的C++

第五章&#xff1a;C在实际项目中的应用 第一课&#xff1a;游戏开发中的C 1. 游戏引擎架构的详细分析 游戏引擎是现代游戏开发的核心&#xff0c;负责处理图形渲染、物理计算、音频管理和用户输入等多项功能。以下是游戏引擎架构的各个主要组成部分及其详细分析。 1.1 渲染…...

一键下载海外youtbe视频 解锁版 支持多分辨率

下载&#xff1a;https://pan.quark.cn/s/387e1110ebe5 【应用名称】&#xff1a;Snaptube 【应用版本】&#xff1a;7.28.0 【应用大小】&#xff1a;26.6M 【测试机型】&#xff1a;小米10S 【适用平台】&#xff1a;Andriod 【版本说明】&#xff1a;解锁版...

Scala内部类的运用

内部类&#xff1a;定义在类里面的类&#xff08;内部类可以访问私有成员用它来操作类的私有成员&#xff0c;封闭性更好&#xff09; class Student{var age18def say():Unit{}class Book{val bookName: Any "Scala程序设计"}}object Test19 {def main(args: Arra…...

【在Linux世界中追寻伟大的One Piece】Socket编程UDP

目录 1 -> UDP网络编程 1.1 -> V1版本 -echo server 1.2 -> V2版本 -DictServer 1.3 -> V2版本 -DictServer(封装版) 1 -> UDP网络编程 1.1 -> V1版本 -echo server 简单的回显服务器和客户端代码。 备注&#xff1a;代码中会用到地址转换函数。 noc…...

机器学习在聚合物及其复合材料中的应用与实践

在当前的工业和科研领域&#xff0c;聚合物及其复合材料因其卓越的物理和化学性能而受到广泛关注。这些材料在航空航天、汽车制造、能源开发和生物医学等多个行业中发挥着至关重要的作用。随着材料科学的发展&#xff0c;传统的实验和理论分析方法已逐渐无法满足新材料研发的需…...

用大模型或者预训练模型对图片进行OCR

背景:使用大模型或者预训练模型(比如来自huggingface上的模型)对图片进行OCR,并将识别结果标记在图片原文的下方。 愿我们终有重逢之时,而你还记得我们曾经讨论的话题。 QQ group 868373192 QQ second group 277356808 要使用预训练模型对图片进行OCR(光学字符识别)…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式

今天是关于AI如何在教学中增强学生的学习体验&#xff0c;我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育&#xff0c;这并非炒作&#xff0c;而是已经发生的巨大变革。教育机构和教育者不能忽视它&#xff0c;试图简单地禁止学生使…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言&#xff1a; 在Java编程中&#xff0c;类的生命周期是指类从被加载到内存中开始&#xff0c;到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期&#xff0c;让读者对此有深刻印象。 目录 ​…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...