【C++设计模式之状态模式:行为型】分析及示例

简介

状态模式(State Pattern)是一种行为型设计模式,它允许对象在内部状态改变时改变其行为,看起来就像是改变了其类。状态模式将对象的状态封装成不同的类,并使得对象在不同状态下有不同的行为。

描述

状态模式通过将每种状态封装成一个独立的类,然后将具体状态类的行为委托给Context类,使得Context类在不同的状态下具有不同的行为。这样,当Context对象的状态发生变化时,它的行为也会随之改变。

原理

状态模式由三个核心组件组成:Context(上下文类)、State(抽象状态类)和ConcreteState(具体状态类)。

  • Context类负责定义切换状态的口,并维护一个对当前状态对象的引用。Context类将具体的状态行为委托给当前状态对象。
  • State类是一个抽象类,定义了具体状态类需要实现的方法,以及在不同状态下Context对象应该具有的行为。
  • ConcreteState类是具体的状态类,实现了State类定义的方法,并根据当前状态下的需求来执行相应的逻辑。

类图

在这里插入图片描述

示例

假设有一个电梯系统,其中电梯有三种状态:打开状态(OpenState)、关闭状态(ClosedState)运行状态(RunningState)。当电梯处于不同的状态时,它的行为也不同。

C++示例代码如下:

#include <iostream>// Context
class Elevator {
public:virtual void open() = 0;virtual void close() = 0;virtual void run() = 0;
};// State
class ElevatorState {
public:virtual void open(Elevator* elevator) = 0;virtual void close(Elevator* elevator) = 0;virtual void run(Elevator* elevator) = 0;
};// ConcreteState
class OpenState : public ElevatorState {
public:void open(Elevator* elevator) override {std::cout << "The elevator is already open." << std::endl;}void close(Elevator* elevator) override {std::cout << "Closing the elevator..." << std::endl;elevator->setState(new ClosedState());}void run(Elevator* elevator) override {std::cout << "Cannot run the elevator while it is open." << std::endl;}
};class ClosedState : public ElevatorState {
public:void open(Elevator* elevator) override {std::cout << "Opening the elevator..." << std::endl;elevator->setState(new OpenState());}void close(Elevator* elevator) override {std::cout << "The elevator is already closed." << std::endl;}void run(Elevator* elevator) override {std::cout << "Running the elevator..." << std::endl;elevator->setState(new RunningState());}
};class RunningState : public ElevatorState {
public:void open(Elevator* elevator) override {std::cout << "Cannot open the elevator while it is running." << std::endl;}void close(Elevator* elevator) override {std::cout << "Cannot close the elevator while it is running." << std::endl;}void run(Elevator* elevator) override {std::cout << "The elevator is already running." << std::endl;}
};// Concrete Context
class ElevatorSystem : public Elevator {
public:ElevatorSystem() {currentState = new ClosedState();}void setState(ElevatorState* state) {delete currentState;currentState = state;}void open() override {currentState->open(this);}void close() override {currentState->close(this);}void run() override {currentState->run(this);}private:ElevatorState* currentState;
};// 使用示例
int main() {ElevatorSystem system;system.open();  // Opening the elevator...system.open();  // The elevator is already open.system.close(); // Closing the elevator...system.run();   // Running the elevator...system.close(); // The elevator is already closed.system.open();  // Opening the elevator...system.run();   // Cannot run the elevator while it is open.return 0;
}

输出结果

Opening the elevator...
The elevator is already open.
Closing the elevator...
Running the elevator...
The elevator is already closed.
Opening the elevator...
Cannot run the elevator while it is open.

解释

在上述示例中,Elevator类是上下文类(Context),它定义了切换状态的接口,并维护一个对当前状态对象的引用。ElevatorState是抽象状态类(State),它定义了具体状态类需要实现的方法。OpenState、ClosedState和RunningState是具体状态类(ConcreteState),它们分别实现了ElevatorState的方法,并根据当前状态下的需求执行相应的逻辑。
在示例中,创建了一个电梯系统(ElevatorSystem),初始状态为关闭状态(ClosedState)。通过调用ElevatorSystem的open、close和run方法来切换电梯的状态,并根据不同的状态执行相应的操作。

结论

状态模式通过将对象的状态封装成独立的类,并委托给Context类来管理,达到了解耦的目的。当对象的状态发生变化时,它的行为也会相应地发生变化。

状态模式适用于以下情况:

  • 当一个对象的行为取决于其状态,并且需要在运行时根据状态改变行为时,可以使用状态模式。
  • 当一个类有很多状态,并且状态之间的转换非常复杂时,可以使用状态模式来将每个状态的行为解耦合。

状态模式常见的应用场景包括订单状态管理、电梯状态控制、游戏角色状态机等。

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

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

相关文章

Qt之显示PDF文件

之前使用过mupdf库&#xff0c;能够成功显示pdf&#xff0c;但是我用着有BUG&#xff0c;不太理解它的代码&#xff0c;搞了好久都不行。后面又试了其他库&#xff0c;如pdfium、popler、下载了很多例程&#xff0c;都跑不起来&#xff01;后面偶然得知xpdf库&#xff0c;看起来…

C++-封装unordered

本期我们来封装实现unordered系列&#xff0c;需要前置知识&#xff0c;没有看过哈希的建议先看看哈希&#xff0c;而且哈希的代码都在这里面&#xff0c;一会要用到 C-哈希Hash-CSDN博客 目录 代码实现 迭代器 const迭代器 全部代码 代码实现 首先我们要把V改为T&#xff…

2023-10-06 LeetCode每日一题(买卖股票的最佳时机含手续费)

2023-10-06每日一题 一、题目编号 714. 买卖股票的最佳时机含手续费二、题目链接 点击跳转到题目位置 三、题目描述 给定一个整数数组 prices&#xff0c;其中 prices[i]表示第 i 天的股票价格 &#xff1b;整数 fee 代表了交易股票的手续费用。 你可以无限次地完成交易&…

STM32复习笔记(一):软件配置工程创建

目录 Preface&#xff1a; Hardware-Configuration & Software-Environment&#xff1a; &#xff08;一&#xff09;新建项目工程 &#xff08;二&#xff09;工程配置 &#xff08;三&#xff09;配置外设 &#xff08;四&#xff09;项目管理 &#xff08;五&…

区别对比表:阿里云轻量服务器和云服务器ECS对照表

阿里云轻量应用服务器和云服务器ECS区别对照表&#xff0c;一看就懂的适用人群、使用场景、优缺点、使用限制、计费方式、网路和镜像系统全方位对比&#xff0c;阿里云服务器网分享ECS和轻量应用服务器区别对照表&#xff1a; 目录 轻量应用服务器和云服务器ECS区别对照表 轻…

51单片机音乐闹钟秒表倒计时整点报时多功能电子钟万年历数码管显示( proteus仿真+程序+原理图+报告+讲解视频)

51单片机音乐闹钟秒表倒计时整点报时多功能电子钟万年历数码管显示( proteus仿真程序原理图报告讲解视频&#xff09; 讲解视频1.主要功能&#xff1a;2.仿真3. 程序代码4.原理图5. 设计报告6. 设计资料内容清单 51单片机音乐闹钟秒表倒计时整点报时多功能电子钟万年历数码管显…

MySQL视图、用户管理

目录 视图概念和操作 视图基本操作 视图规则和限制 用户管理 用户 视图概念和操作 什么是视图&#xff1f; 视图是一个虚拟表&#xff0c;由一个或多个基本表的查询结果组成&#xff08;视图是存储在数据库中的查询的SQL 语句&#xff0c;不在数据库中以存储的数据值集形式…

Verilator: sh: 1: exec: < PATHNAME >: not found

事出有因 I assumed that I install verilator via git clone its source, so I need to set the export VERILATOR_ROOT. At first, due to laziness, I just copy the code directly to my ubuntu. so stupid I am!!! Then, I recoginzed that the pathname is not real, …

wireshark of tshark tools v3.4.0版本 支持json

tshark(1) Install tshark (Wireshark) Ver.3.4.0 on CentOS7 --It must be "ps", "text", "pdml", "psml" or "fields". TCP 协议中的三次握手和四次挥手是 TCP 连接建立和关闭的过程。 三次握手 客户端向服务器发送 SYN…

JMeter学习第一、二、三天

首先&#xff0c;我们来了解一下到底什么是接口测试与性能测试&#xff1a; 接口测试 定义 接口测试主要关注系统组件之间的交互&#xff0c;确保各个接口按预期工作。这包括验证传递的数据、数据格式、调用的频率和其他与接口调用相关的任何限制。 目的 确保系统的各个组件可…

mac清理垃圾的软件有哪些?这三款我最推荐

没错&#xff0c;Mac电脑真的好用&#xff0c;但是清理系统垃圾可不是件容易的事。由于Mac系统的封闭性&#xff0c;系统的缓存垃圾常常隐藏得让人发现不了。不过&#xff0c;别担心&#xff01;有一些专业的Mac清理软件可以帮你解决这一系列问题&#xff0c;让清理垃圾变得轻松…

10链表-单链表构造LinkedList

目录 LeetCode之路——707. 设计链表 分析&#xff1a; Code&#xff1a; LeetCode之路——707. 设计链表 你可以选择使用单链表或者双链表&#xff0c;设计并实现自己的链表。 单链表中的节点应该具备两个属性&#xff1a;val 和 next 。val 是当前节点的值&#xff0c;n…

什么是TF-A项目的长期支持?

安全之安全(security)博客目录导读 问题&#xff1a;Trusted Firmware-A社区每六个月发布一次代码。然而&#xff0c;对于生产中的平台&#xff0c;该策略在维护、重要软件修复的向后兼容性、获得最新的安全缓解措施和整体产品生命周期管理方面不具备可扩展性。 开源软件项目&…

【C++设计模式之原型模式:创建型】分析及示例

简介 原型模式&#xff08;Prototype Pattern&#xff09;是一种创建型设计模式&#xff0c;它允许通过复制已有对象来生成新的对象&#xff0c;而无需再次使用构造函数。 描述 原型模式通过复制现有对象来创建新的对象&#xff0c;而无需显式地调用构造函数或暴露对象的创建…

LDGRB-01 用于在边缘处理人工智能的嵌入式硬件

LDGRB-01 用于在边缘处理人工智能的嵌入式硬件商业和企业中的IT系统正在全面快速发展&#xff0c;一个不断增长的趋势正在将计算能力推向边缘。Gartner预测&#xff0c;到2025年&#xff0c;边缘计算将处理75%的数据由所有用例产生&#xff0c;包括工厂、医疗保健和运输中的用…

[GXYCTF2019]禁止套娃 无回显 RCE 过滤__FILE__ dirname等

扫除git 通过githack 获取index.php <?php include "flag.php"; echo "flag在哪里呢&#xff1f;<br>"; if(isset($_GET[exp])){if (!preg_match(/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i, $_GET[exp])) {if(; preg_replace(/[a-z,_]\(…

Vue中如何进行响应式图像与图片懒加载优化

Vue中响应式图像与图片懒加载优化 在现代的Web开发中&#xff0c;图像在网站性能和用户体验方面扮演着至关重要的角色。然而&#xff0c;加载大量的图像可能会导致网页加载速度变慢&#xff0c;从而影响用户的满意度。为了解决这个问题&#xff0c;Vue.js提供了一些强大的工具…

【gitlab】git push -u origin master 报403

问题描述 gitlab版本&#xff1a;14.0.5 虚拟机版本&#xff1a;centos7 项目&#xff1a;renren-fast 原因分析 .git -> config目录下 url配错 但这个url不是手动配置的&#xff0c;还不知道怎么生成。 解决方法 把配置错误的url改成gitlab的project的url 这样&#…

Android学习之路(20) 进程间通信

IPC IPC为 (Inter-Process Communication) 缩写&#xff0c;称为进程间通信或跨进程通信&#xff0c;指两个进程间进行数据交换的过程。安卓中主要采用 Binder 进行进程间通信&#xff0c;当然也支持其他 IPC 方式&#xff0c;如&#xff1a;管道&#xff0c;Socket&#xff0…

VS Code更改软件的语言

刚刚安装好的 vscode 默认是英文&#xff0c;可以安装中文扩展包。如图&#xff1a; 重启即可更换为中文。 如果想切换为英文&#xff0c;可以 Ctrl Shift P&#xff0c;打开命令面板。 输入 Configure DIsplay Language&#xff0c;如图&#xff1a; 可以在中英文之间切换…