C++ 设计模式之状态模式

C++ 设计模式之状态模式

简介

1、状态模式 (State)是一种行为型设计模式,它允许一个对象在其内部状态发生改变时改变它的行为,对象看起来似乎修改了它的类。该模式主要用于实现一个对象在多种状态转换时能够自动切换到正确的行为。

2、状态模式 (State)应用场景包括但不限于:
2.1、当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为时。
2.2、一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。

3、状态模式 (State)的构成
3.1、状态基类

class State
{
public:
	virtual ~State() {}
	virtual void handleInput(CharacterContext& context, char input) = 0;
	virtual void update(CharacterContext& context) = 0;
};

3.2、具体状态类

class StandingState : public State
{
public:
	void handleInput(CharacterContext& context, char input);
	void update(CharacterContext& context);
};

4、状态模式 (State)的优点
4.1、封装性:状态的变更逻辑和动作执行封装在状态对象中,易于维护和扩展。
4.2、去除庞大的条件分支语句:状态模式通过把各种状态转移逻辑分布到状态对象中,去掉了原系统中对象的行为巨大且复杂的条件分支语句。
4.3、集中化状态管理:所有状态相关的代码都存在于某个State子类中,易于理解。
4.4、维护和扩展更简单:新增状态只需增加新的状态类,不需改变已有的状态类和上下文。

5、状态模式 (State)的缺点
5.1、类膨胀:如果状态很多,而且状态的逻辑也很复杂,就可能会产生很多的状态类,导致系统变得非常庞大。
5.2、依赖性:状态模式把各种状态对象的逻辑都分布在各个状态类中,每个状态类都依赖上下文对象,这增加了各个类之间的依赖性。

简单示例

1、定义

class State
{
public:
	virtual ~State() {}
	virtual void handleInput(CharacterContext& context, char input) = 0;
	virtual void update(CharacterContext& context) = 0;
};

class StandingState : public State
{
public:
	void handleInput(CharacterContext& context, char input);
	void update(CharacterContext& context);
};

class JumpingState : public State
{
public:
	void handleInput(CharacterContext& context, char input);
	void update(CharacterContext& context);
};

class DuckingState : public State
{
public:
	void handleInput(CharacterContext& context, char input);
	void update(CharacterContext& context);
};

class CharacterContext
{
public:
	CharacterContext(State* initialState);
	~CharacterContext();
	void handleInput(char input);
	void changeState(State* newState);
	void update();
private:
	State* currentState;
};

2、实现

void StandingState::handleInput(CharacterContext& context, char input)
{
	if (input == 'D')
	{
		context.changeState(new DuckingState());
	}
	else if (input == 'J')
	{
		context.changeState(new JumpingState());
	}
}

void StandingState::update(CharacterContext& context)
{
	std::cout << "Character is standing." << std::endl;
}

void JumpingState::handleInput(CharacterContext& context, char input)
{
	if (input == 'D')
	{
		context.changeState(new DuckingState());
	}
}

void JumpingState::update(CharacterContext& context)
{
	std::cout << "Character is jumping." << std::endl;
}

void DuckingState::handleInput(CharacterContext& context, char input)
{
	if (input == 'S')
	{
		context.changeState(new StandingState());
	}
}

void DuckingState::update(CharacterContext& context)
{
	std::cout << "Character is ducking." << std::endl;
}

CharacterContext::CharacterContext(State* initialState) : currentState(initialState)
{

}

CharacterContext::~CharacterContext()
{
	delete currentState;
}

void CharacterContext::handleInput(char input)
{
	currentState->handleInput(*this, input);
}

void CharacterContext::changeState(State* newState)
{
	delete currentState;
	currentState = newState;
}

void CharacterContext::update()
{
	currentState->update(*this);
}

3、调用

CharacterContext character(new StandingState());
character.handleInput('D');
character.update();

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

gin 服务端无法使用sse流式nginx配置

我在本地使用 gin 可以流式的将大模型数据传递给前端。但是当我部署到服务器中时&#xff0c;会阻塞一段时间&#xff0c;然后显示一大段文本。 起初我怀疑是gin 没有及时将数据刷到管道中&#xff0c;但是经过测试&#xff0c;还是会阻塞。 c.Writer.(http.Flusher).Flush()最…

HTML5的多线程技术:Web Worker API

Web Workers API 是HTML5的一项技术&#xff0c;它允许在浏览器后台独立于主线程运行脚本&#xff0c;即允许进行多线程处理。这对于执行密集型计算任务特别有用&#xff0c;因为它可以防止这些任务阻塞用户界面&#xff0c;从而保持网页的响应性和交互性。Web Workers在自己的…

CAS服务端部署

部署CAS Cas服务端其实就是一个war包。 在资源\cas\source\cas-server-4.0.0-release\cas-server-4.0.0\modules目录下cas-server-webapp-4.0.0.war 将其改名为cas.war放入tomcat目录下的webapps下。启动tomcat自动解压war包。浏览器输入 登录页面 http://localhost:8080/ca…

43 - 部门工资前三高的所有员工(高频 SQL 50 题基础版)

43 - 部门工资前三高的所有员工 # dense_rank 排名selectDepartment,Employee,Salary from(selectd.name as Department,e.name as Employee,e.salary as Salary,(dense_rank() over (partition by d.name order by e.salary desc)) as rankingfrom Employee e left join Depar…

【设计模式】行为型-状态模式

在变幻的时光中&#xff0c;状态如诗篇般细腻流转。 文章目录 一、可调节的灯光二、状态模式三、状态模式的核心组件四、运用状态模式五、状态模式的应用场景六、小结推荐阅读 一、可调节的灯光 场景假设&#xff1a;我们有一个电灯&#xff0c;它可以被打开和关闭。用户可以…

Nvidia jetson Orin/Nano + 智能座舱摄像头实现车载AI视觉

智能座舱系统包括DMS&#xff08;Driver Monitor System&#xff09;驾驶员疲劳监测系统和OMS乘员监测系统&#xff0c;通过在车内安装摄像头感知驾驶员和乘客的行为以及车内状况&#xff1a;DMS摄像头能够实现驾驶员疲劳监测、驾驶员注意力监测、危险驾驶行为监测以及驾驶员身…

【python】python基于tkinter的学生成绩管理系统(源码+数据文件)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

如何做到高级Kotlin强化实战?(一)

高级Kotlin强化实战&#xff08;一&#xff09; 第一章 Kotlin 入门教程1.Kotlin 入门介绍2.Kotlin 与 Java 比较 第一章 Kotlin 入门教程 1.Kotlin 入门介绍 Kotlin 概述 Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言。它主要是 JetBrains 开发团队所开发出来的编程…

打靶记录——靶机medium_socnet

靶机下载地址 https://www.vulnhub.com/entry/boredhackerblog-social-network,454/ 打靶过程 由于靶机和我的Kali都处于同一个网段&#xff0c;所以使用arpscan二次发现技术来识别目标主机的IP地址 arpscan -l除了192.168.174.133&#xff0c;其他IP都是我VMware虚拟机正…

算法力扣刷题 二十六【459.重复的子字符串】

前言 字符串篇&#xff0c;继续。 记录 二十六【459.重复的子字符串】 一、题目阅读 给定一个非空的字符串 s &#xff0c;检查是否可以通过由它的一个子串重复多次构成。 示例 1: 输入: s "abab" 输出: true 解释: 可由子串 "ab" 重复两次构成。示例…

在TkinterGUI界面显示WIFI网络(ESP32s3)摄像头画面

本实验结合了之前写过的两篇文章Python调用摄像头&#xff0c;实时显示视频在Tkinter界面以及ESP32 S3搭载OV2640摄像头释放热点&#xff08;AP&#xff09;工作模式–Arduino程序&#xff0c;当然如果手头有其他可以获得网络摄像头的URL即用于访问摄像头视频流的网络地址&…

浅谈Tomcat

文章目录 一、什么是Tomcat&#xff1f;二、Tomcat的下载安装三、使用tomcat访问资源 一、什么是Tomcat&#xff1f; Tomcat 就是一个 HTTP 服务器。 前面我们聊了HTTP服务器&#xff0c;像我们在网页输入URL&#xff0c;其实就是在给人家的HTTP服务器发送请求&#xff0c;既…

计算机网络之数据通信原理(中)

上节内容传送口&#xff1a;数据通信原理基础 1.数据传输方式 1.1并行传输 并行传输: 字符编码的各个比特同时传输 特点&#xff1a; 一个比特时间内可传输一个字符&#xff0c;传输速度快&#xff0c;每个比特传输要求一个单独的信道支持&#xff0c;通信成本高&#xf…

红黑树插入删除流程(流程图)

红黑树插入删除流程&#xff08;流程图&#xff09; 红黑树性质 左根右(二叉树&#xff09;根叶黑&#xff08;根节点是黑色的&#xff09;不红红&#xff08;不存在相邻两个红色节点&#xff09;黑路同&#xff08;对于每个节点&#xff0c;从该节点出发到任一空叶节点所经过…

收银系统源码-千呼新零售【全场景收银】

千呼新零售2.0系统是零售行业连锁店一体化收银系统&#xff0c;包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体&#xff0c;线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货、宠物等连锁店使用。 详细介绍请…

intellij idea中使用R语言plot画图无图像问题

1、在intellij idea中使用R语言plot函数时&#xff0c;会遇到各种各样的问题&#xff0c;会出现图片不显示问题&#xff0c; 可以看到&#xff0c;目前我电脑r语言版本为4.2.1&#xff0c;输入下面代码&#xff1a; # # 安装包 # install.packages(ggplot2) # library(ggplot2…

理解MySQL核心技术:外键的概念作用和应用实例

引言 在数据库管理系统&#xff08;DBMS&#xff09;中&#xff0c;外键&#xff08;Foreign Key&#xff09;是维持数据一致性和实现数据完整性的重要工具。本文将详细介绍MySQL外键的基本概念、作用&#xff0c;以及相关的操作指南和应用实例&#xff0c;帮助读者掌握并灵活…

实现了Map接口的HashMap

HashMap 底层主要由以下几个部分组成&#xff1a; 数组 (Node<K,V>[] table): 这是一个数组&#xff0c;存储的是链表的头节点。默认大小为 16。链表 (Linked List): 当发生哈希冲突时&#xff0c;即不同的键具有相同的哈希值&#xff0c;HashMap 使用链表来解决冲突。链…

2024年06月CCF-GESP编程能力等级认证Scratch图形化编程一级真题解析

本文收录于《Scratch等级认证CCF-GESP图形化真题解析》专栏,专栏总目录:点这里,订阅后可阅读专栏内所有文章。 一、单选题(每题 3 分,共 30 分) 第1题 小杨父母带他到某培训机构给他报名参加 CCF 组织的 GESP 认证考试的第 1级,那他可以选择的认证语言有几种?( ) A、…

C++ | Leetcode C++题解之第204题计数质数

题目&#xff1a; 题解&#xff1a; class Solution { public:int countPrimes(int n) {vector<int> primes;vector<int> isPrime(n, 1);for (int i 2; i < n; i) {if (isPrime[i]) {primes.push_back(i);}for (int j 0; j < primes.size() && i …