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

23种设计模式-状态(State)设计模式

文章目录

  • 一.什么是状态模式?
  • 二.状态模式的结构
  • 三.状态模式的应用场景
  • 四.状态模式的优缺点
  • 五.状态模式的C++实现
  • 六.状态模式的JAVA实现
  • 七.代码解释
  • 八.总结

类图: 状态设计模式类图

一.什么是状态模式?

状态模式(State Pattern)是一种行为型设计模式,允许对象在其内部状态改变时改变其行为,看起来就像对象改变了其类。状态模式通过将状态封装为独立的类,使得对象的行为能够根据内部状态动态地改变。
 在状态模式中,Context(环境类)持有一个指向State(状态接口)的引用对象,并通过该对象来进行状态切换。具体的状态通过实现状态接口的不同子类来进行封装。

二.状态模式的结构

  • Context(环境类):用于维护当前状态,并在特定操作时切换状态。它持有一个State对象的引用,用来对状态进行操作。
  • State(状态接口):定义了一个接口,声明了每个具体状态需要实现的行为。
  • ConcreteStateA 和 ConcreteStateB(具体状态类):实现State接口的不同子类,表示对象在不同状态下的行为。
    在这里插入图片描述

三.状态模式的应用场景

  1. 对象行为依赖于状态,且状态在运行时变化:如电梯的状态(上升、下降、停止)、游戏角色的状态(跑步、跳跃、静止)。
  2. 条件语句过多:当对象中有大量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)设计模式

文章目录 一.什么是状态模式&#xff1f;二.状态模式的结构三.状态模式的应用场景四.状态模式的优缺点五.状态模式的C实现六.状态模式的JAVA实现七.代码解释八.总结 类图&#xff1a; 状态设计模式类图 一.什么是状态模式&#xff1f; 状态模式&#xff08;State Pattern&…...

EventListener与EventBus

EventListener JDK JDK1.1开始就提供EventListener&#xff0c;一个标记接口&#xff0c;源码如下&#xff1a; /*** A tagging interface that all event listener interfaces must extend.*/ public interface EventListener { }JDK提供的java.util.EventObject&#xff1…...

Facebook为什么注册失败了?该怎么解决?

有时候用户在尝试注册Facebook账号时可能会遇到各种问题&#xff0c;导致注册失败或遇到困难。小编会为大家分析Facebook注册失败的可能原因&#xff0c;并提供解决方法&#xff0c;帮助大家顺利完成注册流程。 一、Facebook注册失败的可能原因 1. 账号信息问题&#xff1a; …...

前端数据可视化思路及实现案例

目录 一、前端数据可视化思路 &#xff08;一&#xff09;明确数据与目标 &#xff08;二&#xff09;选择合适的可视化图表类型 &#xff08;三&#xff09;数据与图表的绑定及交互设计 &#xff08;四&#xff09;页面布局与样式设计 二、具体案例&#xff1a;使用 Ech…...

【DVWA】Brute Force暴力破解实战

问尔辈 何等样人 自摸心头 再来求我&#xff1b;若汝能 克存忠孝 持身正直 不拜何妨 1.Brute Force(Low) 相关的代码分析 if( isset( $_GET[ Login ] ) ) {// Get username$user $_GET[ username ];// Check the database$query "SELECT * FROM users WHERE user $…...

23种设计模式速记法

前言 在软件开发的过程中&#xff0c;设计模式作为解决常见问题的通用模板&#xff0c;一直是开发者的重要工具。尤其是在面临复杂系统架构和需求变化时&#xff0c;设计模式不仅能够提升代码的可复用性和扩展性&#xff0c;还能大大提高团队之间的协作效率。然而&#xff0c;…...

第7章硬件测试-7.3 功能测试

7.3 功能测试 7.3.1 整机规格测试7.3.2 整机试装测试7.3.3 DFX测试 功能测试包括整机规格、整机试装和整机功能测试&#xff0c;是整机结构和业务相关的测试。 7.3.1 整机规格测试 整机规格测试包括尺寸、重量、温度、功耗等数据。这些测试数据与设计规格进行比对和校验&…...

动态规划子数组系列一>等差数列划分

题目&#xff1a; 解析&#xff1a; 代码&#xff1a; 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浪漫的烟花表白特效》

一、背景介绍 烟花象征着浪漫与激情&#xff0c;将它与表白结合在一起&#xff0c;会创造出别具一格的惊喜效果。使用Python的turtle模块&#xff0c;我们可以轻松绘制出动态的烟花特效&#xff0c;再配合文字表白&#xff0c;打造一段专属的浪漫体验。 接下来&#xff0c;让…...

什么是RESTful API,有什么特点

RESTful API 概述 什么是 RESTful API&#xff1f; RESTful API 是基于 Representational State Transfer&#xff08;表现层状态转移&#xff09;架构风格的 Web 服务接口。REST 是一种设计风格&#xff0c;而不是具体的协议或标准。它定义了一组约束和最佳实践&#xff0c;…...

友思特新闻 | 友思特荣获广州科技创新创业大赛智能装备行业赛初创组优胜企业!

2024年11月19日&#xff0c;第十三届中国创新创业大赛&#xff08;广东广州赛区&#xff09;暨2024年广州科技创新创业大赛智能装备行业赛颁奖典礼隆重举行。 赛事奖项介绍&#xff1a;广州科技创新创业大赛智能装备行业赛 第十三届“中国创新创业大赛&#xff08;广东广州赛区…...

CSS中calc语法不生效

问题起因 在使用calc时发现无法生效&#xff0c;写法是&#xff1a; height:calc(100vh-100px);页面无效果&#xff0c;加空格后就发现有效果了&#xff1a; height:calc(100vh - 100px);这是为什么&#xff1f; calc是什么&#xff1f; css3 的计算属性&#xff0c;用于动态…...

国标GB28181视频平台EasyCVR视频融合平台H.265/H.264转码业务流程

在当今数字化、网络化的视频监控领域&#xff0c;大中型项目对于视频监控管理平台的需求日益增长&#xff0c;特别是在跨区域、多设备、高并发的复杂环境中。EasyCVR视频监控汇聚管理平台正是为了满足这些需求而设计的&#xff0c;它不仅提供了全面的管理功能&#xff0c;还支持…...

ES6 模板字符串详解

ES6 模板字符串详解 ES6&#xff08;ECMAScript 6&#xff09;引入了模板字符串&#xff08;Template Literals&#xff09;&#xff0c;这是一种新的字符串字面量语法&#xff0c;使用反引号&#xff08;&#xff09;来定义字符串。模板字符串不仅支持多行字符串&#xff0c;…...

浏览器插件启动本地程序

浏览器插件支持启动本地程序&#xff0c;且支持win、mac、linux多个平台&#xff0c;使用的是nativeMessaging。nativeMessaging官方api说明。nativeMessaging支持启动本地程序且进行通信。 我们直接拿官方提供的例子进行说明&#xff0c;github地址。 以win为例 1、添加注册…...

Ubuntu ESP32开发环境搭建

文章目录 ESP32开发环境搭建安装ESP-IDF搭建一个最小工程现象 ESP32开发环境搭建 最近有个小项目需要用到能够联网的mcu驱动&#xff0c;准备玩玩esp的芯片&#xff0c;记录下ESP32开发环境搭建的过程。 ESP-IDF 是乐鑫科技为其 ESP32 系列芯片提供的官方开发框架。这个框架主…...

【gitlab】部署

直接RPM安装 部署的方式是&#xff1a;使用外部的nginx作为代理&#xff0c;使用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源在线安装: 添加镜像源&#xff1a;新建 /et…...

vue中路由缓存

vue中路由缓存 问题描述及截图解决思路关键代码及打印信息截图 问题描述及截图 在使用某一平台时发现当列表页码切换后点击某一卡片进入详情页后&#xff0c;再返回列表页时页面刷新了。这样用户每次看完详情回到列表页都得再重新输入自己的查询条件&#xff0c;或者切换分页到…...

Github 2024-11-18 开源项目周报 Top15

根据Github Trendings的统计,本周(2024-11-18统计)共有15个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目8TypeScript项目4Jupyter Notebook项目2Go项目2Shell项目1OpenHands: 人工智能驱动的软件开发代理平台 创建周期:195 天开发语言:P…...

GRCNN使用onnxruntime和tensorrt推理

下载GRCNN项目&#xff1a;https://github.com/skumra/robotic-grasping.git 导出onnx模型&#xff1a; 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.…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么&#xff1f;1.1.2 感知机的工作原理 1.2 感知机的简单应用&#xff1a;基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点&#xff1a; 多级缓存&#xff0c;先查本地缓存&#xff0c;再查Redis&#xff0c;最后才查数据库热点数据重建逻辑使用分布式锁&#xff0c;二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包...

9-Oracle 23 ai Vector Search 特性 知识准备

很多小伙伴是不是参加了 免费认证课程&#xff08;限时至2025/5/15&#xff09; Oracle AI Vector Search 1Z0-184-25考试&#xff0c;都顺利拿到certified了没。 各行各业的AI 大模型的到来&#xff0c;传统的数据库中的SQL还能不能打&#xff0c;结构化和非结构的话数据如何和…...

深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向

在人工智能技术呈指数级发展的当下&#xff0c;大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性&#xff0c;吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型&#xff0c;成为释放其巨大潜力的关键所在&…...

FFmpeg avformat_open_input函数分析

函数内部的总体流程如下&#xff1a; avformat_open_input 精简后的代码如下&#xff1a; int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...

如何在Windows本机安装Python并确保与Python.NET兼容

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

高抗扰度汽车光耦合器的特性

晶台光电推出的125℃光耦合器系列产品&#xff08;包括KL357NU、KL3H7U和KL817U&#xff09;&#xff0c;专为高温环境下的汽车应用设计&#xff0c;具备以下核心优势和技术特点&#xff1a; 一、技术特性分析 高温稳定性 采用先进的LED技术和优化的IC设计&#xff0c;确保在…...