状态模式【行为模式C++】

1.概述

       状态模式是一种行为设计模式, 让你能在一个对象的内部状态变化时改变其行为, 使其看上去就像改变了自身所属的类一样。

  

2.结构

  • State(抽象状态类):定义一个接口用来封装与上下文类的一个特定状态相关的行为,可以有一个或多个行为。
  • ConcreteState(具体状态类):作为抽象状态类的子类,每个子类实现一个与上下文类的一个状态相关的行为。每个具体状态类对应上下文类的一个具体状态,不同的具体状态类其行为有所不同。
  • Context(上下文类):上下文类中维护一个具体状态的实例,通常有多种状态,负责具体状态的切换。

3.实现 

3.1 实例类比

       在日常生活和工作开发中都有状态的问题。你如说马路上的红绿灯,这三个灯光就属于三种状态。再比如说我使用的文档系统,通常有草稿、审阅和批发部三种状态。

       在以往的概念里,我们都会使用if...esle这类语句进行设计,但是这种设计一旦后期的需求发生了改变,那么维护起来相当的复杂!

       一个 文档Document类。 文档可能会处于 草稿Draft 、 ​ 审阅中Moderation和 已发布Published三种状态中的一种。 文档的 publish发布方法在不同状态下的行为略有不同:

  • 处于 草稿状态时, 它会将文档转移到审阅中状态。
  • 处于 审阅状态时, 如果当前用户是管理员, 它会公开发布文档。
  • 处于 已发布状态时, 它不会进行任何操作。  
3.2 具体实现
#include <iostream>
#include <typeinfo>class Context;//抽象状态类
class State {protected:Context *context_;public:virtual ~State() {}void set_context(Context *context) {this->context_ = context;}virtual void Status() = 0;virtual void Handle() = 0;
};//上下文类
class Context {private:State *state_;public:Context(State *state) : state_(nullptr) {this->TransitionTo(state);}~Context() {delete state_;}void TransitionTo(State *state) {std::cout << "Context: Transition to " << typeid(*state).name() << ".\n";if (this->state_ != nullptr)delete this->state_;this->state_ = state;this->state_->set_context(this);}void Request1() {this->state_->Status();}void Request2() {this->state_->Handle();}
};//已发布状态
class PublishedState : public State {
public:void Status() override {std::cout << "处于已发布状态.\n";}void Handle() override {std::cout << "结束...\n";}
};//审阅中状态
class ModerationState : public State {
public:void Status() override {std::cout << "处于审阅中状态.\n";};void Handle() override {this->context_->TransitionTo(new PublishedState);}
};//草稿状态
class DraftState : public State {
public:void Status() override {std::cout << "处于草稿状态.\n";};void Handle() override {this->context_->TransitionTo(new ModerationState);}
};/*** The client code.*/
void ClientCode() {Context *context = new Context(new DraftState);context->Request1();context->Request2();//context->Request1();context->Request2();//context->Request1();context->Request2();delete context;
}int main() {ClientCode();return 0;
}
3.3运行结果

4.状态设计模式优缺点

优点:

      通常对有状态的对象进行编程,我们的解决方案是:思考可能存在的所有状态,然后使用 if-else 或 switch-case 语句来进行状态判断,然后再根据不同的状态进行不同的处理。

      大量的if...else的缺点很明显

  1. 违背开闭原则: 当增加一种状态的时候, 需要修改原来的逻辑
  2. 当状态很多的时候, 代码段很长, 臃肿, 不容易维护, 可扩展性差.

     状态模式可以很好地解决这个问题。封装了转换规则,消除了 if-else、switch-case 等条件判断语句,代码更有层次性,且具备良好的扩展力, 可维护性

缺点
  1. 状态模式的使用必然会增加系统类和对象的个数。
  2. 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。
  3. 状态模式对"开闭原则"的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码。

5.应用场景

  1. 一个操作中含有庞大的多分支结构,并且这些分支取决于对象的状态。
  2. 对象的行为依赖于它的状态(例如某些属性值),状态的改变将导致行为的变化。


 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

甲方安全建设之研发安全-SCA

前言 大多数企业或多或少的会去采购第三方软件&#xff0c;或者研发同学在开发代码时&#xff0c;可能会去使用一些好用的软件包或者依赖包&#xff0c;但是如果这些包中存在恶意代码&#xff0c;又或者在安装包时不小心打错了字母安装了错误的软件包&#xff0c;则可能出现供…

关于SpringCloud,你了解多少?

Why SpringCloud&#xff1f; Spring cloud 是一系列框架的有序集合。它利用 spring boot 的开发便利性巧妙地简化了分布式系统基础设施的开发&#xff0c;如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等&#xff0c;都可以用 spring boot 的开发风格做到一…

用three.js做一个3D汉诺塔游戏(下)

本文由孟智强同学原创。 接上期&#xff1a;《用three.js做一个3D汉诺塔游戏&#xff08;上&#xff09;》 在上一期&#xff0c;我们成功地搭建了基础的 3D 场景。在本期中&#xff0c;我们将对场景进行优化&#xff0c;使其在视觉上更加真实&#xff0c;并为场景中的物体添加…

蓝桥杯物联网竞赛_STM32L071_16_EEPROM

仍然是没有考过的知识点 朴素的讲就是板子中一块不会因为断电重启而导致数值初始化的一片地址 要注意的是有时候容易把板子什么写错导致板子什么地址写坏了导致程序无法烧录&#xff0c;这个时候记得一直按flash键烧录&#xff0c;烧录时会报错&#xff0c;点击确定&#xff0…

活动预告|NineData 创始人CEO叶正盛将参加QCon全球软件开发大会,共话AI大模型技术在数据库DevOps的实践

4月13日下午&#xff0c;NineData创始人&CEO叶正盛即将参加InfoQ中国主办的『QCon全球软件开发大会北京站』的技术大会。在本次技术峰会上&#xff0c;叶正盛将以《AI大模型技术在数据库DevOps的实践》为主题&#xff0c;深入剖析AI大模型技术在数据库DevOps领域的最新进展…

idea新建一个springboot项目

本文分为几个部分&#xff0c; 首先是在idea中新建项目&#xff0c; 然后是配置 项目的目录&#xff08;新建controller、service、dao等&#xff09;&#xff0c; 然后是自定义的一些工具类&#xff08;比如启动后打印地址等&#xff09;。 1.、创建篇 新建项目&#xff0…

概念解读稳定性保障

什么是稳定 百度百科关于稳定的定义&#xff1a; “稳恒固定&#xff1b;没有变动。” 很明显这里的“稳定”是相对的&#xff0c;通常会有参照物&#xff0c;例如 A 车和 B 车保持相同速度同方向行驶&#xff0c;达到相对平衡相对稳定的状态。 那么软件质量的稳定是指什么…

24年做抖音选什么赛道?比起带货,我更倾向你们做这个

我是王路飞。 谁能想到在18年的夏天给无数人留下美好回忆的抖音&#xff0c;如今已经成为了谁也绕不开的创业平台呢&#xff1f; 注意&#xff0c;我说的是“绕不开”。 毕竟在流量为王的时代&#xff0c;流量在哪&#xff0c;我们就要在哪。 而如今&#xff0c;流量全都集…

【热门话题】PyTorch:深度学习领域的强大工具

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 PyTorch&#xff1a;深度学习领域的强大工具一、PyTorch概述二、PyTorch核心特性…

EasyRecovery数据恢复软件2024百度云网盘下载链接

EasyRecovery数据恢复软件是一款功能强大的数据恢复工具&#xff0c;它能够帮助用户从各种存储设备中恢复丢失或误删除的文件数据。无论是由于意外删除、格式化、病毒攻击还是其他原因导致的数据丢失&#xff0c;EasyRecovery都能提供有效的解决方案。 该软件支持多种存储介质…

【攻防世界】mfw(.git文件泄露)

首先进入题目环境&#xff0c;检查页面、页面源代码、以及URL&#xff1a; 发现页面无异常。 使用 dirsearch 扫描网站&#xff0c;检查是否存在可访问的文件或者文件泄露&#xff1a; 发现 可访问界面/templates/ 以及 .git文件泄露&#xff0c;故使用 GItHack 来查看泄露的 …

有图片转成PDF文件格式的方法吗?分享图片转成PDF文件的方法

将图片转换为PDF文件是一个相对简单的过程&#xff0c;但也需要一定的步骤和注意事项。下面&#xff0c;我将详细介绍如何将图片转换为PDF文件&#xff0c;包括所需的工具、步骤以及可能遇到的问题和解决方案。 首先&#xff0c;我们需要一个能够将图片转换为PDF文件的工具。市…

docker-compose yaml指定具体容器网桥ip网段subnet;docker创建即指定subnet;docker取消自启动

1、docker-compose yaml指定具体容器网桥ip网段subnet docker-compose 启动yaml有时可能的容器网段与宿主机的ip冲突导致宿主机上不了网&#xff0c;这时候可以更改yaml指定subnet 宿主机内网一般是192**&#xff0c;这时候容器可以指定172* version: 3.9 services:coredns:…

爬虫 | 垃圾处理设施数据的获取与保存

Hi&#xff0c;大家好&#xff0c;我是半亩花海。本项目通过发送网络请求&#xff08;requests&#xff09;&#xff0c;从指定的 URL 获取垃圾处理设施的相关数据&#xff0c;并将数据保存到 CSV 文件中&#xff0c;以供后续分析和利用。 目录 一、项目结构 二、详细说明 三…

string类——常用函数模拟(C++)

本篇中&#xff0c;将会详细的介绍 Cpp 中 string 的使用&#xff0c;以及 string 类常用函数的模拟实现。对于 string 的内置函数来说&#xff0c;存在很多很冗余的用法&#xff0c;很多函数都有很多种用法&#xff0c;本篇将会讲解常用内置函数的常用用法&#xff0c;模拟函数…

【御控物联】 Java JSON结构转换(2):对象To对象——属性重组

文章目录 一、JSON结构转换是什么&#xff1f;二、案例之《JSON对象 To JSON对象》三、代码实现四、在线转换工具五、技术资料 一、JSON结构转换是什么&#xff1f; JSON结构转换指的是将一个JSON对象或JSON数组按照一定规则进行重组、筛选、映射或转换&#xff0c;生成新的JS…

抽奖系统设计

如何设计一个百万级用户的抽奖系统&#xff1f; - 掘金 如何设计百万人抽奖系统…… 在实现抽奖逻辑时&#xff0c;Redis 提供了多种数据结构&#xff0c;选择哪种数据结构取决于具体的抽奖规则和需求。以下是一些常见场景下推荐使用的Redis数据结构&#xff1a; 无序且唯一奖…

RabbitMQ消息模型之Direct消息模型

Direct消息模型 * 路由模型&#xff1a; * 一个交换机可以绑定多个队列 * 生产者给交换机发送消息时&#xff0c;需要指定消息的路由键 * 消费者绑定队列到交换机时&#xff0c;需要指定所需要消费的信息的路由键 * 交换机会根据消息的路由键将消息转发到对应的队…

LabVIEW和2D激光扫描的受电弓滑板磨耗精确测量

LabVIEW和2D激光扫描的受电弓滑板磨耗精确测量 在电气化铁路运输中&#xff0c;受电弓滑板的健康状况对于保障列车安全行驶至关重要。受电弓滑板作为连接电网与列车的直接介质&#xff0c;其磨损情况直接影响到电能的有效传输及列车的稳定运行。精确、快速测量受电弓滑板磨损情…

数据接口测试工具 Postman 介绍!

此文介绍好用的数据接口测试工具 Postman&#xff0c;能帮助您方便、快速、统一地管理项目中使用以及测试的数据接口。 1. Postman 简介 Postman 一款非常流行的 API 调试工具。其实&#xff0c;开发人员用的更多。因为测试人员做接口测试会有更多选择&#xff0c;例如 Jmeter…