2023-7-12-第十七式状态模式

news2024/12/23 0:00:11


🍿*★,°*:.☆( ̄▽ ̄)/$:*.°★* 🍿

💥💥💥欢迎来到🤞汤姆🤞的csdn博文💥💥💥
💟💟喜欢的朋友可以关注一下,下次更新不迷路💟💟
😆😆😆私聊获取个人订阅号哦,欢迎订阅共同学习😆😆😆
💖💖💖💖可以加入大家庭群聊,一起学习天天有福利💖💖💖💖





🍬本文摘要

在这里插入图片描述

设计方法二十三式之状态模式


目录

  • 🍬本文摘要
  • 😉一、基础概念
  • 🐱‍🐉二、状态模式实现
  • 🎉三、模块之间的关系
  • 🐱‍🚀四、注意事项
  • 🎂五、使用场景
  • 🍳参考文献
  • 🧊文章总结



😉一、基础概念

状态模式是一种行为设计模式,它允许对象在不同的内部状态下改变其行为。在状态模式中,对象根据自身的状态选择不同的策略或算法来完成特定的任务。这种模式支持将复杂的条件分支语句转化为一组相互独立的状态类,并使用面向对象的方式进行管理和切换。

状态模式的核心概念包括三个角色:上下文(Context)、抽象状态(State)和具体状态(Concrete State)。上下文是包含状态的对象,它可以根据当前的状态委派给不同的具体状态处理具体的行为。抽象状态是定义了一个接口或基类,用于描述状态的共同行为。具体状态则实现了抽象状态的接口,在不同的状态下提供独立的行为实现。

通过使用状态模式,我们可以将复杂的条件逻辑分解成一系列简单的状态类,使得代码更加清晰、可扩展和易于维护。此外,状态模式还符合开闭原则,因为我们可以通过添加新的具体状态类来扩展系统的功能,而无需修改上下文类或其他现有的状态类。

总结来说,状态模式通过将对象的行为与其内部状态相联系,提供了一种优雅的方式来处理对象的状态变化和相应的行为变化。


🐱‍🐉二、状态模式实现

在C++中,可以使用类和多态性来实现状态模式。下面是一个简单的示例:

首先,创建一个抽象状态类(State)作为基类,定义了一个纯虚函数用于执行特定状态下的操作。

class State {
public:
    virtual void doAction() = 0;
};

接下来,创建具体状态类(ConcreteState),它们继承自抽象状态类,并实现了相关的操作。

class ConcreteStateA : public State {
public:
    void doAction() override {
        // 执行状态A下的操作
    }
};

class ConcreteStateB : public State {
public:
    void doAction() override {
        // 执行状态B下的操作
    }
};

然后,创建上下文类(Context),该类包含一个指向当前状态对象的指针,并提供了一些方法来切换状态和执行操作。

class Context {
private:
    State* currentState;

public:
    void setState(State* state) {
        currentState = state;
    }

    void performAction() {
        currentState->doAction();
    }
};

最后,我们可以使用这些类来演示状态模式的工作原理。

int main() {
    Context context;
    ConcreteStateA stateA;
    ConcreteStateB stateB;

    context.setState(&stateA);
    context.performAction(); // 执行状态A下的操作

    context.setState(&stateB);
    context.performAction(); // 执行状态B下的操作

    return 0;
}

在上述示例中,上下文(Context)根据当前的状态对象执行相应的操作。通过切换不同的状态对象,上下文可以在运行时改变其行为。这种方式使得状态和行为的关系更加灵活和可扩展,并且能够避免使用大量的条件语句。


🎉三、模块之间的关系

状态模式通常涉及三个主要组件:上下文(Context)、抽象状态(Abstract State)和具体状态(Concrete State)。这些组件之间的关系如下:

  1. 上下文(Context):上下文是包含状态的对象,它维护一个对当前状态对象的引用。上下文提供了一个接口,允许客户端代码设置、获取和切换状态。上下文将实际的操作委派给当前状态对象来执行。

  2. 抽象状态(Abstract State):抽象状态是一个接口或基类,它定义了状态对象的共同行为。这个接口通常包含了在不同状态下需要实现的方法。

  3. 具体状态(Concrete State):具体状态是抽象状态的实现类。每个具体状态类都代表系统中的一个特定状态,并定义了在该状态下应该进行的操作。

在状态模式中,上下文通过持有一个抽象状态对象的引用来维护当前状态,并将请求委托给当前状态对象处理。当状态发生变化时,上下文对象会更新其状态引用,从而切换到不同的具体状态,以便调用相应状态的方法。

状态模式的目标是将与特定状态相关的行为局部化,并使得状态之间的转换更加灵活和可扩展。通过使用状态模式,不同模块之间的关系可以通过上下文和具体状态之间的交互来协调,从而实现更好的封装和解耦。上下文对象可以专注于管理状态,并在需要时委托给相应的状态处理特定的行为。这种模式使得系统更加可维护、可扩展和易于理解。


🐱‍🚀四、注意事项

在使用状态模式时,以下是一些需要注意的事项:

  1. 合适的场景:状态模式适用于当对象的行为依赖于其内部状态,并且该行为在运行时可能发生变化的情况。如果对象有多个状态和相应的操作,并且这些状态之间的转换比较复杂,那么状态模式可以提供一种清晰、可维护的解决方案。

  2. 增加新状态:状态模式支持增加新的具体状态类来扩展系统的功能。因此,在设计状态模式时要考虑到可能的状态增加,并将相应的行为封装在新的具体状态类中。

  3. 上下文与状态的交互:在状态模式中,上下文与具体状态之间的交互是关键。上下文负责切换当前状态并委托请求给当前状态对象处理。确保在上下文中正确管理状态的转换以及对当前状态进行引用的更新。

  4. 状态切换的触发机制:决定何时进行状态切换通常取决于具体的业务逻辑或条件。可以通过事件、用户输入、时间、特定条件等方式来触发状态切换。确保状态切换的触发机制与应用程序的需求相匹配,并避免过于复杂的状态转换逻辑。

  5. 共享状态数据:在状态模式中,具体状态类之间可能需要共享一些状态数据。确保在状态对象之间正确共享和传递必要的状态信息,以便实现正确的行为。

  6. 考虑上下文的复杂性:如果上下文对象需要管理多个状态并且涉及复杂的状态转换逻辑,那么可能需要进一步组织和设计上下文对象,以便更好地管理状态和行为。

  7. 谨慎使用过多的状态:尽管状态模式可以提供灵活的状态管理,但过多的状态可能会导致代码复杂性增加。在设计状态模式时,仔细考虑所需的状态数量,并确保每个状态都有明确的目的和职责。

通过注意以上事项,可以更好地应用状态模式,并实现一个清晰、可扩展的状态管理机制。


🎂五、使用场景

状态模式适用于以下情况和使用场景:

  1. 对象的行为取决于其内部状态:当对象的行为需要根据其内部状态的变化而变化时,可以使用状态模式。例如,一个网络连接对象的行为可能取决于其当前的连接状态(已连接、已断开连接、等待连接等)。

  2. 有多个状态和相应的操作:如果对象有多个状态,并且每个状态都有不同的行为或操作集合,那么状态模式可以提供一种优雅的方式来管理这些行为。状态模式将相关状态的行为封装在具体状态类中,使得状态之间的切换更加清晰和可维护。

  3. 避免大量的条件语句:状态模式可以用于减少大量的条件语句。将复杂的条件分支转换为一组相互独立的状态类可以使代码更简洁、易读和易于修改。每个状态类只关注自己的行为,从而提高了代码的可扩展性和可维护性。

  4. 状态转换的灵活性和可扩展性:状态模式允许添加新的具体状态类来扩展系统的功能。通过增加新的状态类,可以在不影响其他状态类的情况下引入新的行为。这种灵活性和可扩展性使得状态模式在需要频繁添加、修改或调整状态的场景中非常有用。

  5. 分离状态相关的行为:状态模式可以帮助将与特定状态相关的行为集中在单独的状态类中。这种分离使得代码更加模块化和可测试,同时也提供了更好的代码重用性。

  6. 减少条件判断的复杂度:状态模式可将复杂的状态转换逻辑放置到具体状态类中,从而简化上下文对象的代码。通过将状态切换逻辑委托给状态类处理,可以减少上下文对象中的条件判断,使代码更加清晰和可维护。

总的来说,状态模式适用于当对象的行为随着内部状态的变化而变化,并且需要通过封装、分离和管理状态来避免大量的条件语句时。它提供了一种灵活、可扩展的方式来处理复杂的状态转换和相应的行为。


🍳参考文献

🧊文章总结

提示:这里对文章进行总结:

   本文讲了关于状态模式的知识。






更多好文推荐

🍸2021-4月Python 机器学习——中文新闻文本标题分类
🍹2021年4月-(计算机网络)小型校园网络模拟搭建,最全最准确版
🍺2022-10-31-基于用户的协同过滤推荐算法实现+MAE+RMSE
🍻2022-11-28-大数据可视化,特征维度大于50
🥂2023-3-9-一篇简短的文章把C++左右值关系讲的透透彻彻

上一篇
End
下一篇

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IMPALA 查询优化之元数据

目录 说明 背景 问题复现 环境 sql 排查 分析过程 结果分析 总结 说明 sql优化中重要的一环是查询改写,一个表的元数据有利于sql优化器准确的评估sql代价,获取最佳的sql执行计划,如下图所示,本文验证通过加载刷新impala …

Maya文件加载缓慢,这样处理就可以

将场景加载到Maya中时,需要较长时间才能打开场景。 有时,CPU使用率可能会达到100%。 原因: 在文件上工作一段时间后,场景通常会与未使用的显示层、集和节点混淆。这些未使用的图元可能会导致打开文件时出现滞后。 解决方案&…

CMU 15-445 -- Query Processing - 07

CMU 15-445 -- Query Processing - 07 引言Query ProcessingProcessing ModelIterator ModelMaterialization ModelVectorization Model小结 Access MethodsSequential ScanZone MapsLate MaterializationHeap Clustering Index ScanMulti-index ScanIndex Scan Page Sorting E…

文件操作--按格式读写文件

C语言允许按指定格式读写文件。函数fscanf()用于按指定格式从文件读数据。其函数原型为: int fscanf (FILE *fp, const char *format ,...); 其中,第一个参数为文件指针,第2个参数为格式控制参数&#x…

2023届网络安全岗秋招面试题及面试经验分享

Hello,各位小伙伴,我作为一名网络安全工程师曾经在秋招中斩获🔟个offer🌼,并在国内知名互联网公司任职过的职场老油条,希望可以将我的面试的网络安全大厂面试题和好运分享给大家~ 转眼2023年秋招已经到了金…

Linux ❀ Openssh 8.9p1源码升级教程

文章目录 升级操作注意事项:1. 安装依赖2. 执行升级2.1 上传压缩包并保存配置2.2 开始升级 升级操作注意事项: 编译过程需要依赖,必须安装完成!!!SSH服务升级过程可能会导致无法远程连接服务器!!!若必须远程登录必须确认telnet服务可用!!!升…

3D格式转换工具HOOPS Exchange功能大盘点:快速、准确的CAD数据转换SDK!

HOOPS Exchange SDK是一套C软件库,使开发团队能够快速将可靠的二维和三维CAD导入和导出到他们的应用程序中,访问广泛的数据,包括边界表示(B-REP)、产品制造信息(PMI)、模型树、视图、持久性ID、…

C语言—模拟实现memcpy,memmove

1.memcpy函数的介绍与实现 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。 这个函数在遇到 \0 的时候并不会停下来。 如果source和destination有任何的重叠,复制的结果都是未定义的。 void * memcpy ( void * destination, const v…

MySQL原理探索——30 答疑文章(二):用动态的观点看加锁

在第20和21篇文章中,介绍了 InnoDB 的间隙锁、next-key lock,以及加锁规则。 今天这篇答疑文章的主题,即:用动态的观点看加锁。 为了方便理解,我们再一起复习一下加锁规则。这个规则中,包含了两个“原则”、…

电子地图对客户端电脑配置要求

二三维地图是基于canvas和webgl在前端进行的实时渲染,所以首先保证您的客户端是一个具有独立显卡的PC机,而不是虚拟机或低配机器。 其次,性能问题与显示器分辨率以及显卡能力息息相关,通常来说屏幕分辨率越高,越消耗性…

做跨境电商必懂的五大流量运营逻辑,带你玩转流量市场!

一、你上一家是做什么类目的,你们前名是谁,分别是什么样的流量来源? 商家排名一般有四个维度,弟一个维度是消量弟一,弟二个维度是销售额弟一,第三个维度是流量弟一,第四个维度利润弟一。 只要我们找出来自…

【IMX6ULL驱动开发学习】18.中断下半部(tasklet、工作队列、中断线程化)

下图表述了Linux内核的中断处理机制,为了在中断执行时间尽量短和中断处理需完成的工作尽量大之间找到一 个平衡点, Linux将中断处理程序分解为两个半部: 顶半部(Top Half) 和底半部(Bottom Half&#xff09…

centos7安装、使用webbench

简言 1. linux下web服务器性能压测工具有很多,webbench就很不错,而且安装使用都很简单 2. webbench不但能对静态页面的压测,还能对动态页面(ASP,PHP,JAVA,CGI)进行压测。而且支持对含有SSL的安全网站,例如…

Spring cloud alibaba 整合 Sentinel

Sentinel详解 Docker安装1、拉取镜像2、运行容器访问 整合 spring-cloud-alibaba1、引入Maven依赖2、配置控制台3、编写控制器4、启动Sentinel访问自定义异常处理统一异常处理 整合 OpenFeign引入Maven依赖: 配置:编写 Feign 实现指定 Feign 容错类控制器…

ROS2在改造ros1时,报警相关库异常排查

一、在make时,存在以下报警,检查h中是已经包含相关的头文件了,并且也已改为ros2的格式。 二、解决: 检查发现,在CMakelists.txt中未添加相关依赖包,重新添加后,报警解除,编译通过。…

商家们的“疗效”焦虑,巨量引擎、阿里妈妈、腾讯广告们都在怎么满足?

文 | 螳螂观察 作者 | 青月 有人的地方就有营销。 虽然这是一门永不褪色的“生意”,但在增量见顶、红利消失的互联网,数字营销变得越来越听不见“水响”。 就连在号称“史上最卷”的今年618,同台竞技的各大数字营销服务商都在强调自己的“…

difflib 比较文本相似度,找出错误值

在日常的数据分析过程中,我们可能会遇到这样的问题。在处理数据时,有的文本内容是同一类目,但是由于手工输入错误 或者大小写的问题,可能会造成将产品分到不同的类目下,这时候就需要对数据进行清洗。如何实现快速比较…

Selenium基础篇之屏幕截图方法

文章目录 前言一、用途1.捕获页面错误2.调试测试用例3.展示测试结果4.记录页面状态 二、方法1. save_screenshot2. get_screenshot_as_file3. get_screenshot_as_png4. get_screenshot_as_base64 总结 前言 大家好,我是空空star,本篇给大家分享一下Selen…

IDEA+SpringBoot + Mybatis + Shiro+Bootstrap+Mysql智慧仓库系统

IDEASpringBoot Mybatis ShiroBootstrapMysql智慧仓库系统 一、系统介绍1.环境配置 二、系统展示1. 管理员登录2.主页3.货位一览4.入库单5. 库存明细6. 呆滞过期报表7. 转库记录8.入库记录9.出库记录10.出库单11.物料信息12.仓库设置13.用户管理14.操作员管理15.角色管理16.账…

Python实现SMOGN算法解决不平衡数据的回归问题

本文介绍基于Python语言中的smogn包,读取.csv格式的Excel表格文件,实现SMOGN算法,对机器学习、深度学习回归中,训练数据集不平衡的情况加以解决的具体方法。 在不平衡回归问题中,样本数量的不均衡性可能导致模型在预测…