状态模式——C++实现
目录
1. 状态模式简介
2. 代码示例
3. 单例状态对象
4. 状态模式与策略模式的辨析
1. 状态模式简介
状态模式是一种行为型模式。
状态模式的定义:状态模式允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
通俗的说就是一个对象在不同的状态下拥有不同的行为。对象可以拥有多个不同的状态,不同状态下调用同一个接口会产生不同的行为。状态模式通过把状态封装成类,可以很好地维护一个对象的不同状态,并且方便地扩展新的状态。
举个例子:
假如在游戏程序中,要模拟一个怪物。怪物的总血量为100,当血量大于50时,怪物处于亢奋状态,怪物受击时会进行反击;当血量小于等于50时,怪物处于恐慌状态,受击时会选择逃跑。
在这个例子中,怪物具有明确的状态,并且在不同的状态下,同一个接口会有不同的行为。这种情况下就非常适合使用状态模式。
2. 代码示例
下面的代码实现了上文提到的怪物模拟程序:
#if 1#include <iostream>using namespace std;class Monster;
class State
{
protected:Monster* monster_;
public:virtual ~State() {}State(Monster* m) :monster_(m) {}virtual void attacked(int damage) = 0;
};class Monster
{
public:Monster();~Monster();void setState(State* state){curState = state;}State* getExcitedState(){return excitedState;}State* getHorrifiedState(){return horrifiedState;}State* getDeadState(){return deadState;}void attacked(int damage){curState->attacked(damage);}int getCurHealth()const { return health; }int reduceHealth(int damage){health -= damage;health = max(0, health);return health;}
private:State* curState;State* excitedState;State* horrifiedState;State* deadState;int health = 100;
};class ExcitedState : public State
{
public:using State::State;void attacked(int damage){cout << "怪物的当前状态为 ExcitedState" << endl;cout << "怪物尝试反击" << endl;cout << "怪物受到" << damage << "点伤害" << endl;int curHealth = monster_->reduceHealth(damage);cout << "怪物剩余血量:" << curHealth << endl;if (curHealth <= 50){monster_->setState(monster_->getHorrifiedState());cout << "怪物进入 HorrifiedState" << endl;}}
};class HorrifiedState : public State
{
public:using State::State;void attacked(int damage){cout << "怪物的当前状态为 HorrifiedState" << endl;cout << "怪物尝试逃跑" << endl;cout << "怪物受到" << damage << "点伤害" << endl;int curHealth = monster_->reduceHealth(damage);cout << "怪物剩余血量:" << curHealth << endl;if (curHealth <= 0){monster_->setState(monster_->getDeadState());cout << "怪物进入 DeadState" << endl;}}
};class DeadState : public State
{
public:using State::State;void attacked(int damage){cout << "怪物的当前状态为 DeadState" << endl;cout << "怪物已经死亡, 无法受到伤害" << endl;}
};Monster::Monster()
{excitedState = new ExcitedState(this);horrifiedState = new HorrifiedState(this);deadState = new DeadState(this);curState = excitedState;
}Monster::~Monster()
{delete excitedState;delete horrifiedState;delete deadState;
}int main()
{Monster monster;monster.attacked(0);cout << "---------------------" << endl;monster.attacked(30);cout << "---------------------" << endl;monster.attacked(40);cout << "---------------------" << endl;monster.attacked(80);cout << "---------------------" << endl;monster.attacked(100);cout << "---------------------" << endl;return 0;
}#endif
运行结果如下图所示:

代码中增加了死亡状态,当怪物血量小于0时进入了死亡状态。
采用状态模式可以很方便地扩展,增加新的状态会非常便捷。
3. 单例状态对象
当状态对象不含有自身内部的状态时,可以考虑将状态类实现成单例模式
4. 状态模式与策略模式的辨析
状态模式策略模式的结构十分类似,两种模式的差别在于它们的目的不同。
- 对于状态模式来说,可以将对象的一组行为封装在一个状态对象中,context对象(拥有状态的对象)的行为可以随时通过切换不同的状态对象而改变。随着时间的流逝,当前的状态也在多个状态对象中发生改变,以反映context内部的状态,context的行为也会改变。但是对于客户端代码对于context的状态对象可以毫无察觉,不需要了解。context的状态切换是在其内部进行的,客户端代码感知不到。客户端只能感受到context的行为产生了变化,而无需了解其当前的状态是怎么样的。
- 对于策略模式来说,通常需要客户端主动指定context当前所需要的策略对象是哪一个。策略模式允许在程序运行过程中改变策略,但是对于某个context对象来说,通常只有一个当前最适合的策略。策略的切换是通过客户端代码主动发起的。
相关文章:
状态模式——C++实现
目录 1. 状态模式简介 2. 代码示例 3. 单例状态对象 4. 状态模式与策略模式的辨析 1. 状态模式简介 状态模式是一种行为型模式。 状态模式的定义:状态模式允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。 通俗的说就是一个对象…...
3.观察者模式(Observer)
组件协作模式 现代软件专业分工之后的第一个结果是 “框架与应用程序的划分”,“组件协作” 模式通过晚期绑定,来实现框架与应用程序直接的松耦合,是二者之间协作时常用的模式 典型模式 Template Method Strategy Observer /Event 动机(M…...
Kotlin判空辅助工具
1)?.操作符 //执行逻辑 if (person ! null) {person.doSomething() } //表达式 person?.doSomething() 2)?:操作符 //执行逻辑 val c if (a ! null) {a } else {b } //表达式 val c a ?: b 3)!!表达式 var message: String? &qu…...
Electron学习笔记,安装环境(1)
1、支持win7的Electron 的版本是18,这里node.js用的是14版本(node-v14.21.3-x86.msi)云盘有安装包 Electron 18.x (截至2023年仍在维护中): Chromium: 96 Node.js: 14.17.0 2、安装node环境,node-v14.21.3-x86.msi双击运行选择安…...
将 OneLake 数据索引到 Elasticsearch - 第 1 部分
作者:来自 Elastic Gustavo Llermaly 学习配置 OneLake,使用 Python 消费数据并在 Elasticsearch 中索引文档,然后运行语义搜索。 OneLake 是一款工具,可让你连接到不同的 Microsoft 数据源,例如 Power BI、Data Activ…...
【C++】STL介绍 + string类使用介绍 + 模拟实现string类
目录 前言 一、STL简介 二、string类 1.为什么学习string类 2.标准库中的string类 3.auto和范围for 4.迭代器 5.string类的常用接口说明 三、模拟实现 string类 前言 本文带大家入坑STL,学习第一个容器string。 一、STL简介 在学习C数据结构和算法前,我…...
Hive:基本查询语法
和oracle一致的部分 和oracle不一样的部分 排序 oracle中,在升序排序中,NULL 值被视为最大的值;在降序排序中,NULL 值被视为最小的值。 在MySQL中,NULL 被视为小于任何非空值。 在Hive中, NULL是最小的; Hive除了可以用order…...
日志收集Day008
1.zk集群优化 修改zookeeper的堆内存大小,一般情况下,生产环境给到2G足以,如果规模较大可以适当调大到4G。 (1)配置ZK的堆内存 vim /app/softwares/zk/conf/java.env export JAVA_HOME/sortwares/jdk1.8.0_291 export JVMFLAGS"-Xms2…...
【解决方案】VMware虚拟机adb连接宿主机夜神模拟器
1、本机(宿主机,系统windows10)ip为192.168.31.108 2、运行模拟器后本机cmd查看端口为62026 3、VMware虚拟机(系统,kali)adb连接192.168.31.108:62026报错 failed to connect to 192.168.31.108:16416: Co…...
基于金融新闻的大型语言模型强化学习在投资组合管理中的应用
“Financial News-Driven LLM Reinforcement Learning for Portfolio Management” 论文地址:https://arxiv.org/pdf/2411.11059 摘要 本研究探索了如何通过将大语言模型(LLM)支持的情感分析融入强化学习(RL)中&#…...
脚本运行禁止:npm 无法加载文件,因为在此系统上禁止运行脚本
问题与处理策略 1、问题描述 npm install -D tailwindcss执行上述指令,报如下错误 npm : 无法加载文件 D:\nodejs\npm.ps1,因为在此系统上禁止运行脚本。 有关详细信息,请参阅 https:/go.microsoft.com/fwlink/?LinkID135170 中的 about_…...
借DeepSeek-R1东风,开启创业新机遇
DeepSeek-R1的崛起 DeepSeek-R1的推出引发了广泛关注,在AI领域引起了一阵旋风。作为新一代的智能模型,它在多项任务中表现出了卓越的能力。普通人可以借助这个强大的工具,开启属于自己的创业之路,抓住时代带来的机遇。 内容创作…...
C# lock使用详解
总目录 前言 在 C# 多线程编程中,lock 关键字是一种非常重要的同步机制,用于确保同一时间只有一个线程可以访问特定的代码块,从而避免多个线程同时操作共享资源时可能出现的数据竞争和不一致问题。以下是关于 lock 关键字的详细使用介绍。 一…...
简易CPU设计入门:控制总线的剩余信号(四)
项目代码下载 请大家首先准备好本项目所用的源代码。如果已经下载了,那就不用重复下载了。如果还没有下载,那么,请大家点击下方链接,来了解下载本项目的CPU源代码的方法。 CSDN文章:下载本项目代码 上述链接为本项目…...
使用 lock4j-redis-template-spring-boot-starter 实现 Redis 分布式锁
在分布式系统中,多个服务实例可能同时访问和修改共享资源,从而导致数据不一致的问题。为了解决这个问题,分布式锁成为了关键技术之一。本文将介绍如何使用 lock4j-redis-template-spring-boot-starter 来实现 Redis 分布式锁,从而…...
22_解析XML配置文件_List列表
解析XML文件 需要先 1.【加载XML文件】 而 【加载XML】文件有两种方式 【第一种 —— 使用Unity资源系统加载文件】 TextAsset xml Resources.Load<TextAsset>(filePath); XmlDocument doc new XmlDocument(); doc.LoadXml(xml.text); 【第二种 —— 在C#文件IO…...
编译器gcc/g++ --【Linux基础开发工具】
文章目录 一、背景知识二、gcc编译选项1、预处理(进行宏替换)2、编译(生成汇编)3、汇编(生成机器可识别代码)4、链接(生成可执行文件或库文件) 三、动态链接和静态链接四、静态库和动态库1、动静态库2、编译…...
58.界面参数传递给Command C#例子 WPF例子
界面参数的传递,界面参数是如何从前台传送到后台的。 param 参数是从界面传递到命令的。这个过程通常涉及以下几个步骤: 数据绑定:界面元素(如按钮)的 Command 属性绑定到视图模型中的 RelayCommand 实例。同时&#x…...
games101-(5/6)
光栅化 投影完成之后,视图区域被确定在从[-1,1]的单位矩阵中,下一步就是光栅化 长宽比:ratio 垂直的可视角度:fild-of-view 可以看到的y 轴的范围,角度越小 越接近正交投影 屏幕坐标系 、 将多边形转化成像素 显示…...
人工智能在计算机视觉中的应用与创新发展研究
一、引言 1.1 研究背景与意义 1.1.1 研究背景 在当今数字化与智能化飞速发展的时代,人工智能已成为推动各领域变革的核心力量,而计算机视觉作为人工智能领域中极具活力与潜力的重要分支,正发挥着日益关键的作用。计算机视觉旨在赋予计算机…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
若依登录用户名和密码加密
/*** 获取公钥:前端用来密码加密* return*/GetMapping("/getPublicKey")public RSAUtil.RSAKeyPair getPublicKey() {return RSAUtil.rsaKeyPair();}新建RSAUti.Java package com.ruoyi.common.utils;import org.apache.commons.codec.binary.Base64; im…...
WebRTC调研
WebRTC是什么,为什么,如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…...
Java后端检查空条件查询
通过抛出运行异常:throw new RuntimeException("请输入查询条件!");BranchWarehouseServiceImpl.java // 查询试剂交易(入库/出库)记录Overridepublic List<BranchWarehouseTransactions> queryForReagent(Branch…...
Linux-进程间的通信
1、IPC: Inter Process Communication(进程间通信): 由于每个进程在操作系统中有独立的地址空间,它们不能像线程那样直接访问彼此的内存,所以必须通过某种方式进行通信。 常见的 IPC 方式包括&#…...
ubuntu中安装conda的后遗症
缘由: 在编译rk3588的sdk时,遇到编译buildroot失败,提示如下: 提示缺失expect,但是实测相关工具是在的,如下显示: 然后查找借助各个ai工具,重新安装相关的工具,依然无解。 解决&am…...
GeoServer发布PostgreSQL图层后WFS查询无主键字段
在使用 GeoServer(版本 2.22.2) 发布 PostgreSQL(PostGIS)中的表为地图服务时,常常会遇到一个小问题: WFS 查询中,主键字段(如 id)莫名其妙地消失了! 即使你在…...
