23种设计模式-状态(State)设计模式
文章目录
- 一.什么是状态模式?
- 二.状态模式的结构
- 三.状态模式的应用场景
- 四.状态模式的优缺点
- 五.状态模式的C++实现
- 六.状态模式的JAVA实现
- 七.代码解释
- 八.总结
类图: 状态设计模式类图
一.什么是状态模式?
状态模式(State Pattern)是一种行为型设计模式,允许对象在其内部状态改变时改变其行为,看起来就像对象改变了其类。状态模式通过将状态封装为独立的类,使得对象的行为能够根据内部状态动态地改变。
在状态模式中,Context(环境类)持有一个指向State(状态接口)的引用对象,并通过该对象来进行状态切换。具体的状态通过实现状态接口的不同子类来进行封装。
二.状态模式的结构
- Context(环境类):用于维护当前状态,并在特定操作时切换状态。它持有一个State对象的引用,用来对状态进行操作。
- State(状态接口):定义了一个接口,声明了每个具体状态需要实现的行为。
- ConcreteStateA 和 ConcreteStateB(具体状态类):实现State接口的不同子类,表示对象在不同状态下的行为。

三.状态模式的应用场景
- 对象行为依赖于状态,且状态在运行时变化:如电梯的状态(上升、下降、停止)、游戏角色的状态(跑步、跳跃、静止)。
- 条件语句过多:当对象中有大量if-else或switch语句判断状态时,可以考虑使用状态模式进行优化。
四.状态模式的优缺点
-
优点:
- 封装状态转换:将状态与相关行为封装在一个类中,便于维护和扩展。
- 避免条件判断:通过多态替代了条件判断,代码更具可读性和扩展性。
-
缺点:
- 类数量增加:每个状态需要一个类,可能会导致类数量较多。
五.状态模式的C++实现
#include <iostream>
#include <memory>// 前置声明,避免循环引用
class State;// 环境类(Context)
class Context {
private:std::shared_ptr<State> state; // 当前状态public:// 设置当前状态void setState(std::shared_ptr<State> newState) {state = newState;}// 执行请求,调用当前状态的Handle方法void request();
};// 状态接口(State)
class State {
public:virtual void handle(Context& context) = 0; // 定义纯虚函数,具体状态类需实现
};// 具体状态类 A(ConcreteStateA)
class ConcreteStateA : public State {
public:void handle(Context& context) override {std::cout << "ConcreteStateA handling request.\n";// 状态切换:可以切换到状态 Bcontext.setState(std::make_shared<ConcreteStateB>());}
};// 具体状态类 B(ConcreteStateB)
class ConcreteStateB : public State {
public:void handle(Context& context) override {std::cout << "ConcreteStateB handling request.\n";// 状态切换:可以切换回状态 Acontext.setState(std::make_shared<ConcreteStateA>());}
};// 环境类方法的实现
void Context::request() {if (state) {state->handle(*this); // 调用当前状态的 handle 方法}
}// 测试代码
int main() {Context context;// 初始化状态为 Acontext.setState(std::make_shared<ConcreteStateA>());// 执行多次请求,测试状态切换context.request(); // ConcreteStateA 处理请求,然后切换到 ConcreteStateBcontext.request(); // ConcreteStateB 处理请求,然后切换到 ConcreteStateAcontext.request(); // ConcreteStateA 处理请求,然后切换到 ConcreteStateBreturn 0;
}
六.状态模式的JAVA实现
// 抽象状态类
abstract class State {public abstract void Handle(Context context);
}// 具体状态A
class ConcreteStateA extends State {@Overridepublic void Handle(Context context) {System.out.println("ConcreteStateA: Handling request and transitioning to ConcreteStateB.");context.setState(new ConcreteStateB());}
}// 具体状态B
class ConcreteStateB extends State {@Overridepublic void Handle(Context context) {System.out.println("ConcreteStateB: Handling request and transitioning to ConcreteStateA.");context.setState(new ConcreteStateA());}
}// 环境类 (Context)
class Context {private State state;public Context(State state) {this.state = state;}public void setState(State state) {this.state = state;}public void Request() {if (state != null) {state.Handle(this);}}
}// 客户端代码
public class StatePatternDemo {public static void main(String[] args) {// 初始状态为 ConcreteStateAContext context = new Context(new ConcreteStateA());// 调用多次 Request,观察状态切换context.Request(); // 从 A 切换到 Bcontext.Request(); // 从 B 切换到 Acontext.Request(); // 再次从 A 切换到 B}
}
七.代码解释
- Context 类:
- Context类持有一个指向State的指针(使用智能指针std::shared_ptr来管理状态对象的生命周期)。
- 它包含一个request()方法,用于请求当前状态处理相应的操作。
- setState()方法用于切换状态,方便在运行时改变state的引用指向不同的State对象。
- State 接口:
- State接口中定义了一个纯虚函数handle(),表示不同状态下的行为。
- Context通过调用state->handle(*this)来执行当前状态的具体行为。
- ConcreteStateA 和 ConcreteStateB:
- ConcreteStateA和ConcreteStateB是State接口的具体实现类,每个类都定义了各自的handle()方法。
- 在ConcreteStateA::handle()中,Context的状态被切换为ConcreteStateB,而在ConcreteStateB::handle()中,状态切换回ConcreteStateA。
- 这种状态切换体现了状态模式的核心思想,即状态内部控制状态转换,客户端不需要关心状态如何切换。
- 测试代码:
- 在main函数中,创建Context对象context,并将初始状态设为ConcreteStateA。
- 通过多次调用request()方法,可以看到状态在ConcreteStateA和ConcreteStateB之间切换,体现出对象行为随状态变化而变化的特点。
八.总结
状态模式是一种非常适合解决对象行为依赖于状态变化的设计模式。通过将状态封装为独立的类,状态模式使得代码更加清晰和易于维护,避免了条件判断语句的冗余和复杂性。每个具体状态类不仅实现了各自的行为,还决定了状态切换的逻辑,从而让状态之间的转换更为灵活。
关键点:
- 状态模式封装了对象内部的状态变化逻辑,使得对象的行为可以动态改变。
- 通过多态,状态模式避免了条件判断,使代码更具可扩展性。
- 状态切换由具体状态类控制,客户端只需与Context交互,降低了耦合度。
相关文章:
23种设计模式-状态(State)设计模式
文章目录 一.什么是状态模式?二.状态模式的结构三.状态模式的应用场景四.状态模式的优缺点五.状态模式的C实现六.状态模式的JAVA实现七.代码解释八.总结 类图: 状态设计模式类图 一.什么是状态模式? 状态模式(State Pattern&…...
EventListener与EventBus
EventListener JDK JDK1.1开始就提供EventListener,一个标记接口,源码如下: /*** A tagging interface that all event listener interfaces must extend.*/ public interface EventListener { }JDK提供的java.util.EventObject࿱…...
Facebook为什么注册失败了?该怎么解决?
有时候用户在尝试注册Facebook账号时可能会遇到各种问题,导致注册失败或遇到困难。小编会为大家分析Facebook注册失败的可能原因,并提供解决方法,帮助大家顺利完成注册流程。 一、Facebook注册失败的可能原因 1. 账号信息问题: …...
前端数据可视化思路及实现案例
目录 一、前端数据可视化思路 (一)明确数据与目标 (二)选择合适的可视化图表类型 (三)数据与图表的绑定及交互设计 (四)页面布局与样式设计 二、具体案例:使用 Ech…...
【DVWA】Brute Force暴力破解实战
问尔辈 何等样人 自摸心头 再来求我;若汝能 克存忠孝 持身正直 不拜何妨 1.Brute Force(Low) 相关的代码分析 if( isset( $_GET[ Login ] ) ) {// Get username$user $_GET[ username ];// Check the database$query "SELECT * FROM users WHERE user $…...
23种设计模式速记法
前言 在软件开发的过程中,设计模式作为解决常见问题的通用模板,一直是开发者的重要工具。尤其是在面临复杂系统架构和需求变化时,设计模式不仅能够提升代码的可复用性和扩展性,还能大大提高团队之间的协作效率。然而,…...
第7章硬件测试-7.3 功能测试
7.3 功能测试 7.3.1 整机规格测试7.3.2 整机试装测试7.3.3 DFX测试 功能测试包括整机规格、整机试装和整机功能测试,是整机结构和业务相关的测试。 7.3.1 整机规格测试 整机规格测试包括尺寸、重量、温度、功耗等数据。这些测试数据与设计规格进行比对和校验&…...
动态规划子数组系列一>等差数列划分
题目: 解析: 代码: public int numberOfArithmeticSlices(int[] nums) {int n nums.length;int[] dp new int[n];int ret 0;for(int i 2; i < n; i){dp[i] nums[i] - nums[i-1] nums[i-1] - nums[i-2] ? dp[i-1]1 : 0;ret dp[i…...
《Python浪漫的烟花表白特效》
一、背景介绍 烟花象征着浪漫与激情,将它与表白结合在一起,会创造出别具一格的惊喜效果。使用Python的turtle模块,我们可以轻松绘制出动态的烟花特效,再配合文字表白,打造一段专属的浪漫体验。 接下来,让…...
什么是RESTful API,有什么特点
RESTful API 概述 什么是 RESTful API? RESTful API 是基于 Representational State Transfer(表现层状态转移)架构风格的 Web 服务接口。REST 是一种设计风格,而不是具体的协议或标准。它定义了一组约束和最佳实践,…...
友思特新闻 | 友思特荣获广州科技创新创业大赛智能装备行业赛初创组优胜企业!
2024年11月19日,第十三届中国创新创业大赛(广东广州赛区)暨2024年广州科技创新创业大赛智能装备行业赛颁奖典礼隆重举行。 赛事奖项介绍:广州科技创新创业大赛智能装备行业赛 第十三届“中国创新创业大赛(广东广州赛区…...
CSS中calc语法不生效
问题起因 在使用calc时发现无法生效,写法是: height:calc(100vh-100px);页面无效果,加空格后就发现有效果了: height:calc(100vh - 100px);这是为什么? calc是什么? css3 的计算属性,用于动态…...
国标GB28181视频平台EasyCVR视频融合平台H.265/H.264转码业务流程
在当今数字化、网络化的视频监控领域,大中型项目对于视频监控管理平台的需求日益增长,特别是在跨区域、多设备、高并发的复杂环境中。EasyCVR视频监控汇聚管理平台正是为了满足这些需求而设计的,它不仅提供了全面的管理功能,还支持…...
ES6 模板字符串详解
ES6 模板字符串详解 ES6(ECMAScript 6)引入了模板字符串(Template Literals),这是一种新的字符串字面量语法,使用反引号()来定义字符串。模板字符串不仅支持多行字符串,…...
浏览器插件启动本地程序
浏览器插件支持启动本地程序,且支持win、mac、linux多个平台,使用的是nativeMessaging。nativeMessaging官方api说明。nativeMessaging支持启动本地程序且进行通信。 我们直接拿官方提供的例子进行说明,github地址。 以win为例 1、添加注册…...
Ubuntu ESP32开发环境搭建
文章目录 ESP32开发环境搭建安装ESP-IDF搭建一个最小工程现象 ESP32开发环境搭建 最近有个小项目需要用到能够联网的mcu驱动,准备玩玩esp的芯片,记录下ESP32开发环境搭建的过程。 ESP-IDF 是乐鑫科技为其 ESP32 系列芯片提供的官方开发框架。这个框架主…...
【gitlab】部署
直接RPM安装 部署的方式是:使用外部的nginx作为代理,使用https方式。 1、下载安装文件 gitlab-ce-17.0.3-ce.0.el7.x86_64.rpm 2、安装 yum install gitlab-ce-17.0.3-ce.0.el7.x86_64.rpm 或者安装yum源在线安装: 添加镜像源:新建 /et…...
vue中路由缓存
vue中路由缓存 问题描述及截图解决思路关键代码及打印信息截图 问题描述及截图 在使用某一平台时发现当列表页码切换后点击某一卡片进入详情页后,再返回列表页时页面刷新了。这样用户每次看完详情回到列表页都得再重新输入自己的查询条件,或者切换分页到…...
Github 2024-11-18 开源项目周报 Top15
根据Github Trendings的统计,本周(2024-11-18统计)共有15个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目8TypeScript项目4Jupyter Notebook项目2Go项目2Shell项目1OpenHands: 人工智能驱动的软件开发代理平台 创建周期:195 天开发语言:P…...
GRCNN使用onnxruntime和tensorrt推理
下载GRCNN项目:https://github.com/skumra/robotic-grasping.git 导出onnx模型: import torchnet torch.load("trained-models/jacquard-rgbd-grconvnet3-drop0-ch32/epoch_42_iou_0.93") x torch.rand(1, 4, 300, 300).cuda() torch.onnx.…...
apt-cyg项目架构与开发指南:理解开源包管理器的设计思路
apt-cyg项目架构与开发指南:理解开源包管理器的设计思路 【免费下载链接】apt-cyg Apt-cyg, an apt-get like tool for Cygwin 项目地址: https://gitcode.com/gh_mirrors/ap/apt-cyg apt-cyg是一个为Cygwin环境设计的强大包管理器,它模仿了Debia…...
新手入门指南:在快马平台用AI生成代码理解云桌面基础概念
今天想和大家分享一个特别适合新手理解云桌面基础概念的实践方法。作为一个刚接触云计算的小白,我最初对"一台主机创建多个云桌面"这个概念也是一头雾水,直到在InsCode(快马)平台上尝试用AI生成代码来模拟这个过程,才真正搞明白其中…...
iptables实战指南:从链表关系到规则配置的完整解析
1. iptables基础概念与核心组件 第一次接触iptables时,我盯着那些复杂的规则配置看了整整一个下午。后来才发现,理解iptables的关键在于掌握它的"四表五链"架构。简单来说,iptables就像是一个多层安检系统,数据包要经过…...
张量维度操控心法:从reshape到升维降维,吃透PyTorch形状操作的底层逻辑
✨ 张量维度操控心法:从reshape到升维降维,吃透PyTorch形状操作的底层逻辑🔐 张量形状操作的黄金法则:形状是视角,内容是本质🔧 reshape函数:零侵入的形状重塑神器核心原理与执行规则实操代码与…...
从零部署到实战标注:SUSTechPOINTS 3D点云标注平台全流程指南
1. 为什么选择SUSTechPOINTS进行3D点云标注 在自动驾驶研发过程中,3D点云标注是个绕不开的苦差事。我最早用过不少商业标注工具,不是价格贵得离谱,就是功能残缺不全。直到去年团队接手一个校企合作项目,才发现南方科技大学开源的这…...
Chandra OCR多平台部署指南:Windows WSL2/Mac Metal/Linux Docker全搞定
Chandra OCR多平台部署指南:Windows WSL2/Mac Metal/Linux Docker全搞定 1. Chandra OCR核心能力解析 Chandra是Datalab.to在2025年10月开源的布局感知OCR模型,与传统OCR工具最大的区别在于它能完整保留文档的排版结构信息。想象一下:当你扫…...
基于vue的错题管理系统[vue]-计算机毕业设计源码+LW文档
摘要:随着在线教育的发展,错题管理作为学习过程中的重要环节,其信息化管理需求日益增长。本文旨在设计并实现一个基于Vue框架的错题管理系统,通过对系统需求进行深入分析,采用合适的技术架构和开发技术,完成…...
Pixel Language Portal快速上手:无需Python基础的Streamlit镜像开箱即用
Pixel Language Portal快速上手:无需Python基础的Streamlit镜像开箱即用 1. 什么是Pixel Language Portal? Pixel Language Portal(像素语言跨维传送门)是一款基于腾讯Hunyuan-MT-7B核心引擎构建的创新翻译工具。它最大的特点是…...
Phi-4-mini-reasoning效果展示:同参数量级中推理准确率超Llama3-8B实测对比
Phi-4-mini-reasoning效果展示:同参数量级中推理准确率超Llama3-8B实测对比 1. 开篇亮点:小模型的大智慧 Phi-4-mini-reasoning这款仅有3.8B参数的轻量级开源模型,正在重新定义我们对小模型能力的认知。作为专为数学推理、逻辑推导和多步解…...
别再手动转格式了!用Python的docx2pdf库5行代码搞定Word转PDF(Windows/Mac通用教程)
5行代码终结格式转换焦虑:Python自动化Word转PDF全攻略 每次市场部门催着要电子合同时,你是不是还在手忙脚乱地点击"另存为PDF"?当运营团队需要批量生成上百份产品手册时,是否还在忍受重复机械的格式转换操作࿱…...
