【30】c++设计模式——>状态模式

状态模式概述

状态模式是一种行为型设计模式,它可以让一个对象在其内部状态发生变化时更改其行为。通过将每个状态封装成一个独立的类,我们可以使状态之间互相独立,并且使得状态的切换变得更加灵活、可扩展。(多个状态之间可以相互转换)
在状态模式中,我们通常会定义一个抽象状态类(Abstract State),以及多个具体状态类(Concrete States)。每个具体状态都会实现抽象状态类中定义的各种操作,并且在需要时执行状态转换。
此外,还有一个环境类(Context),它包含了当前状态,并且在状态发生变化时调用各个状态类的方法来实现状态转换。因为这些状态类都实现了同一个接口,所以环境类不需要知道具体状态的细节,只需要调用相应的方法即可。

如何理解状态类和环境类

电视遥控器
开电视学习
关电视睡觉
静音打游戏

电视遥控器的例子

一个电视遥控器。电视遥控器有三种状态:开机状态、关机状态和静音状态。我们可以通过简单地按遥控器上的按钮来更改状态。为了实现这个功能,首先我们需要定义一个抽象状态类,该类将定义所有可能的操作:

class TVState {
public:virtual void onButtonPressed(TVRemote* remote) = 0;virtual void offButtonPressed(TVRemote* remote) = 0;virtual void muteButtonPressed(TVRemote* remote) = 0;
};

TVState中包含了三种操作:开机、关机和静音。这些操作在不同的状态下可能会有不同的实现方式,因此我们需要在具体状态类中进行实现。

// 具体状态类:开机状态
class OnState : public TVState {
public:void onButtonPressed(TVRemote* remote) override {std::cout << "The TV is already on." << std::endl;}void offButtonPressed(TVRemote* remote) override {std::cout << "Turning off the TV." << std::endl;remote->setState(new OffState());}void muteButtonPressed(TVRemote* remote) override {std::cout << "Muting the TV." << std::endl;remote->setState(new MuteState());}
};// 具体状态类:关机状态
class OffState : public TVState {
public:void onButtonPressed(TVRemote* remote) override {std::cout << "Turning on the TV." << std::endl;remote->setState(new OnState());}void offButtonPressed(TVRemote* remote) override {std::cout << "The TV is already off." << std::endl;}void muteButtonPressed(TVRemote* remote) override {std::cout << "Cannot mute the TV when it's turned off." << std::endl;}
};// 具体状态类:静音状态
class MuteState : public TVState {
public:void onButtonPressed(TVRemote* remote) override {std::cout << "Unmuting the TV." << std::endl;remote->setState(new OnState());}void offButtonPressed(TVRemote* remote) override {std::cout << "Turning off the TV." << std::endl;remote->setState(new OffState());}void muteButtonPressed(TVRemote* remote) override {std::cout << "The TV is already muted." << std::endl;}
};

在这些具体状态类中,我们重写了TVState中定义的所有操作,并且在需要时执行状态转换。例如,在开机状态下按下静音键会将遥控器的状态更改为“静音状态”。
接下来,让我们定义环境类(Context):

class TVRemote {
private:TVState* currentState;public:TVRemote() {currentState = new OffState();}void setState(TVState* state) {currentState = state;}void pressOnButton() {currentState->onButtonPressed(this);}void pressOffButton() {currentState->offButtonPressed(this);}void pressMuteButton() {currentState->muteButtonPressed(this);}
};

在环境类中,我们维护了当前状态,并且在状态发生变化时调用相应的具体状态类方法。我们还定义了三个按键操作:开机、关机和静音。
现在,我们可以使用电视遥控器来测试状态模式的实现了:

int main() {TVRemote remote;remote.pressOnButton();    // Turning on the TV.remote.pressOnButton();    // The TV is already on.remote.pressMuteButton();  // Muting the TV.remote.pressMuteButton();  // The TV is already muted.remote.pressOffButton();   // Turning off the TV.remote.pressOffButton();   // The TV is already off.remote.pressMuteButton();  // Cannot mute the TV when it's turned off.remote.pressOnButton();    // Turning on the TV.remote.pressMuteButton();  // Unmuting the TV.return 0;
}

通过上面的代码,我们可以看到当我们按下不同的键时,电视遥控器的状态会发生相应的变化。

完整代码

remote.cpp

#include "remote.h"
#include "state.h"TVRemote::TVRemote(TVState* State )
{currentState = State;
}void TVRemote::setState(TVState* state)
{currentState = state;
}void TVRemote::pressOnButton()
{currentState->onButtonPressed(this);
}void TVRemote::pressOffButton()
{currentState->offButtonPressed(this);
}void TVRemote::pressMuteButton()
{currentState->muteButtonPressed(this);
}

remote.h

#pragma once
class TVState; //这里没声明,报了一堆错class TVRemote
{
private:TVState* currentState;public:TVRemote(TVState* State);void setState(TVState* state);void pressOnButton();void pressOffButton();void pressMuteButton();
};

state.h

#pragma once
#include"remote.h"class TVState {
public:virtual void onButtonPressed(TVRemote* remote) = 0; // 开机virtual void offButtonPressed(TVRemote* remote) = 0; // 关机virtual void muteButtonPressed(TVRemote* remote) = 0; // 静音
};// 具体状态类:关机状态
class OffState : public TVState
{
public:void onButtonPressed(TVRemote* remote) override;void offButtonPressed(TVRemote* remote) override;void muteButtonPressed(TVRemote* remote) override;
};// 具体状态类:开机状态
class OnState : public TVState
{
public:void onButtonPressed(TVRemote* remote) override;void offButtonPressed(TVRemote* remote) override;void muteButtonPressed(TVRemote* remote) override;
};// 具体状态类:静音状态
class MuteState : public TVState {
public:void onButtonPressed(TVRemote* remote) override;void offButtonPressed(TVRemote* remote) override;void muteButtonPressed(TVRemote* remote) override;
};

state.cpp

#include<iostream>
#include "state.h"
#include "remote.h"// 具体状态类:关机状态
void OffState::onButtonPressed(TVRemote* remote) 
{std::cout << "Turning on the TV." << std::endl;remote->setState(new OnState());
}void OffState::offButtonPressed(TVRemote* remote) 
{std::cout << "The TV is already off." << std::endl;
}void OffState::muteButtonPressed(TVRemote* remote)
{std::cout << "Cannot mute the TV when it's turned off." << std::endl;
}// 具体状态类:开机状态
void OnState::onButtonPressed(TVRemote* remote) 
{std::cout << "The TV is already on." << std::endl;
}void OnState::offButtonPressed(TVRemote* remote) 
{std::cout << "Turning off the TV." << std::endl;remote->setState(new OffState());
}void OnState::muteButtonPressed(TVRemote* remote)
{std::cout << "Muting the TV." << std::endl;remote->setState(new MuteState());
}// 具体状态类:静音状态
void MuteState::onButtonPressed(TVRemote* remote)
{std::cout << "Unmuting the TV." << std::endl;remote->setState(new OnState());
}void MuteState::offButtonPressed(TVRemote* remote) 
{std::cout << "Turning off the TV." << std::endl;remote->setState(new OffState());
}void MuteState::muteButtonPressed(TVRemote* remote)
{std::cout << "The TV is already muted." << std::endl;
}

main.cpp

#include <iostream>
using namespace std;
#include "state.h"
#include "remote.h"int main() {TVState* off = new MuteState;TVRemote remote(off);remote.pressOnButton();    // Turning on the TV.remote.pressOnButton();    // The TV is already on.remote.pressMuteButton();  // Muting the TV.remote.pressMuteButton();  // The TV is already muted.remote.pressOffButton();   // Turning off the TV.remote.pressOffButton();   // The TV is already off.remote.pressMuteButton();  // Cannot mute the TV when it's turned off.remote.pressOnButton();    // Turning on the TV.remote.pressMuteButton();  // Unmuting the TV.return 0;
}

在这里插入图片描述

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

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

相关文章

uni-app 小宠物 - 会说话的小鸟

在 template 中 <view class"container"><view class"external-shape"><view class"face-box"><view class"eye-box eye-left"><view class"eyeball-box eyeball-left"><span class"…

适合在虚拟化环境中部署 Kubernetes 的三个场景

在《虚拟化 vs. 裸金属&#xff1a;K8s 部署环境架构与特性对比》文章中&#xff0c;我们从架构和特性的角度&#xff0c;对比了在虚拟化和裸金属环境部署 Kubernetes 的优劣势&#xff0c;并在文末列举了两者更适合的应用场景。本文&#xff0c;我们将聚焦以虚拟化环境支持 K8…

ubuntu20.04下安装nc

前言 nc在网络渗透测试中非常好用&#xff0c;这里的主要记一下Ubuntu20.04中nc的安装 编译安装 第一种方式是自己编译安装&#xff0c;先下载安装包 nc.zip wget http://sourceforge.net/projects/netcat/files/netcat/0.7.1/netcat-0.7.1.tar.gz/download -O netcat-0.7.…

线性代数-Python-03:矩阵的变换 - 手写Matrix Transformation及numpy中的用法

文章目录 一、代码仓库二、旋转矩阵的推导及图形学中的矩阵变换2.1 让横坐标扩大a倍&#xff0c;纵坐标扩大b倍2.2 关于x轴翻转2.3 关于y轴翻转2.4 关于原点翻转&#xff08;x轴&#xff0c;y轴均翻转&#xff09;2.5 沿x方向错切2.6 沿y方向错切2.7 旋转2.8 单位矩阵2.9 矩阵的…

ES在企业项目中的实战总结,彻底掌握ES的使用

通过之前两篇文章 了解了ES的核心概念和基础使用学习进阶的DSL语法处理复杂的查询 这段时间通过在本企业代码中对ES框架的使用&#xff0c;总结了不少经验。主要分为三点 企业封装了ES原生的api&#xff0c;需要使用企业项目提供的接口实现 -------简单使用&#xff08;本章节目…

PyCharm中文使用详解

PyCharm是一个Python IDE&#xff0c;可以帮助程序员节省时间&#xff0c;提高生产力。那么具体怎么用呢&#xff1f;本文介绍了PyCharm的安装、插件、外部工具、专业功能等&#xff0c;希望对大家有所帮助。 之前没有系统介绍过PyCharm。如何配置环境&#xff0c;如何DeBug&a…

Go语言入门心法(十四): Go操作Redis实战

Go语言入门心法(一): 基础语法 Go语言入门心法(二): 结构体 Go语言入门心法(三): 接口 Go语言入门心法(四): 异常体系 Go语言入门心法(五): 函数 Go语言入门心法(六): HTTP面向客户端|服务端编程 Go语言入门心法(七): 并发与通道 Go语言入门心法(八): mysql驱动安装报错o…

数据安全小课堂开讲啦!看这里!

数据安全小课堂开讲啦&#xff01;看这里&#xff01; 1、什么是数据&#xff1f; 《数据安全法》第三条明确&#xff0c;本法所称的数据&#xff0c;就是指任何以电子或者其他方式对信息的记录。小到个人使用手机、电脑等电子产品时浏览的网页、下载的应用、存储的文件&…

前端数据可视化之【Echarts下载使用】

目录 &#x1f31f;下载&#x1f31f;浏览器引入&#x1f31f;模块化引入 &#x1f31f;使用&#x1f31f;基本使用步骤 &#x1f31f;绘制一个简单的图表&#x1f31f;写在最后 &#x1f31f;下载 &#x1f31f;浏览器引入 官网下载界面&#xff1a;官方网站 或 Echarts中文…

前端,CSS,背景颜色跟随轮播图片改变而改变(附源码)

首先看效果&#xff01; 比如轮播图时红色&#xff0c;那么背景的底色也是红色&#xff0c;轮播图时黄色&#xff0c;背景的底色也是黄色&#xff0c;这就是根据轮播图的图片切换&#xff0c;而改变背景颜色随轮播图颜色一致 话不多说&#xff0c;直接上代码&#xff01;非常简…

css-边框流水线

效果图&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html><head><meta charset"utf-8"><meta name"viewport" content"initial-scale1.0, user-scalableno" /><title></title><style type&…

centos搭建elastic集群

1、环境可以在同一台集群上搭建elastic&#xff0c;也可以在三台机器上搭建&#xff0c;这次演示的是在同一台机器搭建机器。 2、下载elastic &#xff1a;https://www.elastic.co/cn/downloads/past-releases#elasticsearch 2、​​​​​​ tar -zxvf elasticsearch-xxx-版…

软硬件架构分层总结

一、前言 软件系统很多架构图我们经常看到是这样的三段 就是这三段就可以演化出很多层 二、硬件架构分层 硬件层&#xff0c;基本是计算机硬件的体系结构&#xff0c;包括硬盘设备&#xff0c;cpu&#xff0c;内存&#xff0c;控制器&#xff0c;运算器&#xff0c;寄存器&am…

淘宝API接口(商品信息获取,订单管理,库存管理,数据分析和优化)

淘宝API接口可以用于许多业务场景&#xff0c;以下是一些常见的应用场景&#xff1a; 商品信息获取&#xff1a;通过淘宝API接口可以获取商品的详细信息&#xff0c;包括商品标题、价格、库存、销量、评价等数据。这些信息可以用于在自己的网站或应用程序中展示商品&#xff0…

0基础学习PyFlink——使用PyFlink的SQL进行字数统计

在《0基础学习PyFlink——Map和Reduce函数处理单词统计》和《0基础学习PyFlink——模拟Hadoop流程》这两篇文章中&#xff0c;我们使用了Python基础函数实现了字&#xff08;符&#xff09;统计的功能。这篇我们将切入PyFlink&#xff0c;使用这个框架实现字数统计功能。 PyFl…

Vue中使用Web Serial API连接串口,实现通信交互

Vue中使用Web Serial API连接串口&#xff0c;实现通信交互 Web Serial API&#xff0c;web端通过串口与硬件通信; 该API是JS本身 navigator 对象上就独有的&#xff0c;所以与Vue和React框架开发都没有太大的关系&#xff0c; 串口是一个双向通信接口&#xff0c;允许字节发送…

Visual Studio Code (VS Code)安装教程

Visual Studio Code&#xff08;简称“VS Code”&#xff09;。 1.下载安装包 VS Code的官网&#xff1a; Visual Studio Code - Code Editing. Redefined 首先提及一下&#xff0c;vscode是不需要破解操作的&#xff1b; 第一步&#xff0c;看好版本&#xff0c;由于我的系…

几个Web自动化测试框架的比较:Cypress、Selenium和Playwright

介绍&#xff1a;Web自动化测试框架对于确保Web应用程序的质量和可靠性至关重要。它们帮助开发人员和测试人员自动执行重复性任务&#xff0c;跨多个浏览器和平台执行测试&#xff0c;并在开发早期发现问题。 以下仅代表作者观点&#xff1a; 本文探讨来3种流行的Web自动化测…

17 结构型模式-享元模式

1 享元模式介绍 2 享元模式原理 3 享元模式实现 抽象享元类可以是一个接口也可以是一个抽象类,作为所有享元类的公共父类, 主要作用是提高系统的可扩展性. //* 抽象享元类 public abstract class Flyweight {public abstract void operation(String extrinsicState); }具体享…

【计算机网络】UDP的报文结构和注意事项

UDP&#xff08;User Datagram Protocol&#xff0c;用户数据报协议&#xff09;是一种无连接的协议&#xff0c;它在传输层中提供了简单、不可靠的数据传输服务。与TCP&#xff08;Transmission Control Protocol,传输控制协议&#xff09;不同&#xff0c;UDP不需要建立连接&…