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

【设计模式】【行为型模式(Behavioral Patterns)】之状态模式(State Pattern)

1. 设计模式原理说明

状态模式(State Pattern) 是一种行为设计模式,它允许对象在其内部状态发生变化时改变其行为。这个模式的核心思想是使用不同的类来表示不同的状态,每个状态类都封装了与该状态相关的特定行为。当对象的状态发生改变时,对象会切换到另一个状态对象,从而改变了它的行为。

主要角色
  1. Context(上下文):定义客户感兴趣的接口,维护一个对当前状态对象的引用。
  2. State(抽象状态):定义一个接口,用以封装与Context的一个特定状态相关的行为。
  3. ConcreteState(具体状态):实现State接口,每种状态都对应一个具体的状态类,封装了与该状态相关的特定行为。

2. UML 类图及解释

UML 类图
+-----------------+
|     Context     |
|-----------------|
| - state: State  |
| + setState(state: State) |
| + request()     |
+-----------------+^||v
+-----------------+
|     State       |
|-----------------|
| + handle(context: Context) |
+-----------------+^||v
+-----------------+
| ConcreteStateA  |
|-----------------|
| + handle(context: Context) |
+-----------------+^||v
+-----------------+
| ConcreteStateB  |
|-----------------|
| + handle(context: Context) |
+-----------------+
类图解释
  • Context:定义客户感兴趣的接口,维护一个对当前状态对象的引用。当状态变化时,调用setState方法更新当前状态。
  • State:定义一个接口,用以封装与Context的一个特定状态相关的行为。
  • ConcreteStateA 和 ConcreteStateB:实现State接口,每种状态都对应一个具体的状态类,封装了与该状态相关的特定行为。

3. 代码案例及逻辑详解

Java 代码案例
// 抽象状态
interface State {void handle(Context context);
}// 具体状态 A
class ConcreteStateA implements State {@Overridepublic void handle(Context context) {System.out.println("Current state is ConcreteStateA");context.setState(new ConcreteStateB());}
}// 具体状态 B
class ConcreteStateB implements State {@Overridepublic void handle(Context context) {System.out.println("Current state is ConcreteStateB");context.setState(new ConcreteStateA());}
}// 上下文
class Context {private State state;public Context(State state) {this.state = state;}public void setState(State state) {this.state = state;}public void request() {state.handle(this);}
}// 客户端
public class Client {public static void main(String[] args) {Context context = new Context(new ConcreteStateA());context.request();  // 输出: Current state is ConcreteStateAcontext.request();  // 输出: Current state is ConcreteStateB}
}
C++ 代码案例
#include <iostream>// 抽象状态
class State {
public:virtual void handle(Context* context) = 0;
};// 具体状态 A
class ConcreteStateA : public State {
public:void handle(Context* context) override {std::cout << "Current state is ConcreteStateA" << std::endl;context->setState(new ConcreteStateB());}
};// 具体状态 B
class ConcreteStateB : public State {
public:void handle(Context* context) override {std::cout << "Current state is ConcreteStateB" << std::endl;context->setState(new ConcreteStateA());}
};// 上下文
class Context {
private:State* state;
public:Context(State* state) : state(state) {}void setState(State* state) {delete this->state;this->state = state;}void request() {state->handle(this);}
};// 客户端
int main() {Context* context = new Context(new ConcreteStateA());context->request();  // 输出: Current state is ConcreteStateAcontext->request();  // 输出: Current state is ConcreteStateBdelete context;return 0;
}
Python 代码案例
# 抽象状态
class State:def handle(self, context):pass# 具体状态 A
class ConcreteStateA(State):def handle(self, context):print("Current state is ConcreteStateA")context.set_state(ConcreteStateB())# 具体状态 B
class ConcreteStateB(State):def handle(self, context):print("Current state is ConcreteStateB")context.set_state(ConcreteStateA())# 上下文
class Context:def __init__(self, state):self.state = statedef set_state(self, state):self.state = statedef request(self):self.state.handle(self)# 客户端
if __name__ == "__main__":context = Context(ConcreteStateA())context.request()  # 输出: Current state is ConcreteStateAcontext.request()  # 输出: Current state is ConcreteStateB
Go 代码案例
package mainimport ("fmt"
)// 抽象状态
type State interface {handle(context *Context)
}// 具体状态 A
type ConcreteStateA struct{}func (s *ConcreteStateA) handle(context *Context) {fmt.Println("Current state is ConcreteStateA")context.setState(&ConcreteStateB{})
}// 具体状态 B
type ConcreteStateB struct{}func (s *ConcreteStateB) handle(context *Context) {fmt.Println("Current state is ConcreteStateB")context.setState(&ConcreteStateA{})
}// 上下文
type Context struct {state State
}func (c *Context) setState(state State) {c.state = state
}func (c *Context) request() {c.state.handle(c)
}// 客户端
func main() {context := &Context{state: &ConcreteStateA{}}context.request()  // 输出: Current state is ConcreteStateAcontext.request()  // 输出: Current state is ConcreteStateB
}

4. 总结

状态模式 是一种行为设计模式,它允许对象在其内部状态发生变化时改变其行为。这个模式的核心思想是使用不同的类来表示不同的状态,每个状态类都封装了与该状态相关的特定行为。当对象的状态发生改变时,对象会切换到另一个状态对象,从而改变了它的行为。

主要优点
  1. 简化对象的操作:将与特定状态相关的行为封装在状态对象中,使上下文对象的操作更加简单。
  2. 高内聚低耦合:状态对象之间的转换逻辑被封装在状态对象内部,减少了上下文对象的复杂性。
  3. 易于扩展:新增状态时,只需添加新的状态类,而不需要修改现有的代码。
主要缺点
  1. 类的膨胀:每增加一个新的状态就需要增加一个新的类,可能导致类的数量急剧增加。
  2. 状态转换逻辑复杂:状态之间的转换逻辑可能变得复杂,尤其是当状态数量较多时。
适用场景
  • 当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变其行为时。
  • 当控制一个对象的状态转换的条件表达式过于复杂时。
  • 当代码中包含大量与对象状态有关的条件语句时,可以考虑使用状态模式来简化这些条件语句。

相关文章:

【设计模式】【行为型模式(Behavioral Patterns)】之状态模式(State Pattern)

1. 设计模式原理说明 状态模式&#xff08;State Pattern&#xff09; 是一种行为设计模式&#xff0c;它允许对象在其内部状态发生变化时改变其行为。这个模式的核心思想是使用不同的类来表示不同的状态&#xff0c;每个状态类都封装了与该状态相关的特定行为。当对象的状态发…...

QML学习 —— 34、视频媒体播放器(附源码)

效果 说明 您可以单独使用MediaPlayer播放音频内容(如音频),也可以将其与VideoOutput结合使用以渲染视频。VideoOutput项支持未转换、拉伸和均匀缩放的视频演示。有关拉伸均匀缩放演示文稿的描述,请参见fillMode属性描述。 播放可能出错问题 出现的问题:      DirectS…...

【深度学习|特征增强模块】FFN(前馈神经网络)和E_FFN(增强型前馈神经网络)是transformer特征增强的重要组成部分!

【深度学习|特征增强模块】FFN&#xff08;前馈神经网络&#xff09;和E_FFN&#xff08;增强型前馈神经网络&#xff09;是transformer特征增强的重要组成部分&#xff01; 【深度学习|特征增强模块】FFN&#xff08;前馈神经网络&#xff09;和E_FFN&#xff08;增强型前馈神…...

【Qt】控件7

1.QTextEdit的简单使用 使用简单的QTextEdit,获取到的内容显示到标签上 使用textChanged信号 在槽函数中需要获取QTextEdit的内容&#xff0c;对应操作是&#xff1a; QString curorui->textEdit->toPlainText();然后显示到标签上&#xff0c;对应操作是&#xff1a; …...

F12抓包14_修改网页图片网页保存到本地

课程大纲 1、修改网页图片&#xff08;2种方式二选一&#xff09; 修改网页图片&#xff0c;需要定位到图片标签&#xff0c;修改<img>标签的属性。2种方法&#xff1a; 1. 修改为网络图片url。缺点&#xff1a;url失效&#xff0c;图片无法显示。 2. 修改为图片base64&a…...

源代码检测,内附实际案例

源代码安全审计是依据国标GB/T 34944-2017、GB/T 34944-2017&#xff0c;结合专业源代码扫描工具对各种程序语言编写的源代码进行安全审计。能够为客户提供包括安全编码规范咨询、源代码安全现状评测、定位源代码中存在的安全漏洞、分析漏洞风险、给出修改建议等一系列服务。 源…...

1138:将字符串中的小写字母转换成大写字母

【题目描述】 给定一个字符串&#xff0c;将其中所有的小写字母转换成大写字母。 【输入】 输入一行&#xff0c;包含一个字符串&#xff08;长度不超过100&#xff0c;可能包含空格&#xff09;。 【输出】 输出转换后的字符串。 【输入样例】 helloworld123Ha 【输出样例】…...

《C++ 人工智能模型邂逅云平台:集成之路的策略与要点全解析》

在当今数字化浪潮汹涌澎湃的时代&#xff0c;人工智能无疑是引领技术变革的核心力量。而 C以其卓越的性能和高效的资源利用&#xff0c;成为开发人工智能模型的有力武器。与此同时&#xff0c;云平台所提供的强大计算能力、灵活的存储资源以及便捷的服务部署&#xff0c;为人工…...

【ArcGISPro】Sentinel-2数据处理

错误 默认拉进去只组织了4个波段,但是实际有12个波段 解决方案 数据下载 Sentinel-2 数据下载-CSDN博客 数据处理 数据查看 创建镶嵌数据集 在数据管理工具箱中找到创建镶嵌数据集...

Unity中的简易TCP服务器/客户端

在本文中&#xff0c;我将向你介绍一个在Unity中实现的简单TCP服务器脚本,和一个简单的客户端脚本. 脚本 MyTcpServer 允许Unity应用创建一个TCP服务器&#xff0c;监听客户端的连接、异步处理客户端消息&#xff0c;并通过事件与Unity应用中的其他模块进行通信。 MyTcpServe…...

Spring Boot 3.4 正式发布,结构化日志!

1 从 Spring Boot 3.3 升级到 3.4 1.1 RestClient 和 RestTemplate 新增对 RestClient 和 RestTemplate 自动配置的支持&#xff0c;可用 Reactor Netty 的 HttpClient 或 JDK 的 HttpClient。支持的客户端优先级&#xff1a; Apache HTTP Components (HttpComponentsClient…...

技术文档,they are my collection!

工作 今天这篇文章&#xff0c;献给一直撰写技术文档的自己。我自认为是公司中最爱写文档的人了&#xff0c;我们是一个不到40人的小公司&#xff0c;公司作风没有多么严谨&#xff0c;领导也不会要求我们写技术文档。但是从入职初至今&#xff0c;我一直保持着写技术文档…...

详解Qt之QtMath Qt数学类

文章目录 QtMath详解前言QtMath简介QtMath中的函数1. 三角函数1.1 qSin1.2 qCos 2. 指数与对数函数2.1 qExp2.2 qLn 3. 幂运算与平方根3.1 qPow3.2 qSqrt QtMath的优势1. 一致性与跨平台支持2. 与Qt生态系统集成3. 简洁性 总结 QtMath详解 前言 在C的开发中&#xff0c;数学运…...

人工智能与人类:共创未来的新篇章

数年前&#xff0c;当人工智能还停留在实验室的时候&#xff0c;很少有人能想到它会如此迅速地融入我们的日常生活。如今&#xff0c;从手机上的语音助手&#xff0c;到自动驾驶汽车&#xff0c;从智能家居到医疗诊断&#xff0c;AI的身影无处不在。这让我想起了20世纪初电力普…...

4.6 JMeter HTTP信息头管理器

欢迎大家订阅【软件测试】 专栏&#xff0c;开启你的软件测试学习之旅&#xff01; 文章目录 前言1 HTTP信息头管理器的位置2 常见的HTTP请求头3 添加 HTTP 信息头管理器4 应用场景 前言 在 JMeter 中&#xff0c;HTTP信息头管理器&#xff08;HTTP Header Manager&#xff09…...

非交换几何与黎曼ζ函数:数学中的一场革命性对话

非交换几何与黎曼ζ函数&#xff1a;数学中的一场革命性对话 非交换几何&#xff08;Noncommutative Geometry, NCG&#xff09;是数学的一个分支领域&#xff0c;它将经典的几何概念扩展到非交换代数的框架中。非交换代数是一种结合代数&#xff0c;其中乘积不是交换性的&…...

【设计模式】【行为型模式(Behavioral Patterns)】之观察者模式(Observer Pattern)

1. 设计模式原理说明 观察者模式&#xff08;Observer Pattern&#xff09; 是一种行为设计模式&#xff0c;它定义了一种一对多的依赖关系&#xff0c;当一个对象的状态发生改变时&#xff0c;所有依赖于它的对象都会得到通知并自动更新。这种模式非常适合处理事件驱动系统&a…...

文件导入-使用java反射修改日期数据

文件导入时&#xff0c;时间类型通常不能直接导出&#xff0c;以下方法为批量处理类中日期类型转字符串类型。 Date/Datetime --> String(yyyy-mm-dd)Field[] declaredFields HrAviationstudentMonitorDTO.class.getDeclaredFields(); for (Field field : declaredFields) …...

【网络安全设备系列】10、安全审计系统

0x00 定义: 网络安全审计系统针对互联网行为提供有效的行为审计、内容审计、行为报警、行为控制及相关审计功能。从管理层面提供互联网的 有效监督&#xff0c;预防、制止数据泄密。满足用户对互联网行为审计备案及 安全保护措施的要求&#xff0c;提供完整的上网记录&#xf…...

Apache Maven Assembly 插件简介

Apache Maven Assembly 插件是一个强大的工具&#xff0c;允许您以多种格式&#xff08;如 ZIP、TAR 和 JAR&#xff09;创建项目的分发包。 该插件特别适用于将项目与其依赖项、配置文件和其他必要资源一起打包。 通过使用 Maven Assembly 插件&#xff0c;您可以将项目作为…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

Django RBAC项目后端实战 - 03 DRF权限控制实现

项目背景 在上一篇文章中&#xff0c;我们完成了JWT认证系统的集成。本篇文章将实现基于Redis的RBAC权限控制系统&#xff0c;为系统提供细粒度的权限控制。 开发目标 实现基于Redis的权限缓存机制开发DRF权限控制类实现权限管理API配置权限白名单 前置配置 在开始开发权限…...

英国云服务器上安装宝塔面板(BT Panel)

在英国云服务器上安装宝塔面板&#xff08;BT Panel&#xff09; 是完全可行的&#xff0c;尤其适合需要远程管理Linux服务器、快速部署网站、数据库、FTP、SSL证书等服务的用户。宝塔面板以其可视化操作界面和强大的功能广受国内用户欢迎&#xff0c;虽然官方主要面向中国大陆…...

简单聊下阿里云DNS劫持事件

阿里云域名被DNS劫持事件 事件总结 根据ICANN规则&#xff0c;域名注册商&#xff08;Verisign&#xff09;认定aliyuncs.com域名下的部分网站被用于非法活动&#xff08;如传播恶意软件&#xff09;&#xff1b;顶级域名DNS服务器将aliyuncs.com域名的DNS记录统一解析到shado…...

codeforces C. Cool Partition

目录 题目简述&#xff1a; 思路&#xff1a; 总代码&#xff1a; https://codeforces.com/contest/2117/problem/C 题目简述&#xff1a; 给定一个整数数组&#xff0c;现要求你对数组进行分割&#xff0c;但需满足条件&#xff1a;前一个子数组中的值必须在后一个子数组中…...