C++ 命令模式

news2025/1/23 7:04:59

什么是命令模式?

  • 将请求转换为一个包含与请求相关的所有信息的独立对象。从而使你可以用不同的请求方法进行参数化,并且能够对请求进行排队、记录请求日志以及撤销请求操作。
  • 命令模式属于行为设计模式

如何理解命令模式

命令模式很像我们订外卖(淘宝),用户下单,订单中包裹了商户的信息及订餐数量,外卖平台作为接收者将订单再通知到商户,商户执行操作。

命令模式的步骤

源自ChatGpt的总结

  1. 定义一个 Command 抽象类,它声明了一个抽象的 execute() 方法,该方法用于执行命令。
  2. 创建一个实现了 Command 抽象类的实体类,该类实现了 execute() 方法,用于执行具体的命令。
  3. 创建一个 Invoker 类,该类持有 Command 类的一个实例,并调用实例的 execute() 方法来实现命令的调用。
  4. 创建客户端,在客户端中创建一个具体的 Command 对象,并设置它的接收者。
  5. 创建 Invoker 对象,并将创建的 Command 对象设置到 Invoker 对象中。
  6. 调用 Invoker 对象的 execute() 方法来执行命令。

代码描述

我们这里用户头像为例子

  • 首先需要接口类
/*通用命令*/
class Command {
public:
	virtual ~Command() {}
	virtual void Execute() const = 0;
};
/*通用处理人*/
class Receiver {
public:
	virtual void DoFuncA(const int a)     = 0;
	virtual void DoFuncB(const int b) = 0;
};
  • 创建具体命令
/*实例化一个厨师类的处理人*/
class CookReceiver : public Receiver {
public:
	explicit CookReceiver(const std::string& cook_name) : cook_name_(cook_name) {}
	void DoFuncA(const int a) { 
		std::cout << "->cook " << cook_name_ << " Receiver: Working sum= " << a << std::endl; 
	}
	void DoFuncB(const int b){
		std::cout << "->cook " << cook_name_ << "  Receiver: Working food weight=" << b << std::endl;
	}

private:
	std::string cook_name_;
};
/*实例化一条简单命令*/
class MilkCommand : public Command {
private:
	int sum_;

public:
	explicit MilkCommand(int sum) : sum_(sum) {}
	void Execute() const override { std::cout << "->The customer need milk= " << this->sum_ << std::endl; }
};
/*实例化一条复杂的命令*/
class SteakCommand : public Command {

public:
	explicit SteakCommand(std::shared_ptr<Receiver> receiver_cook, int sum, int weight)
		: sum_(sum), weight_(weight), receiver_cook_(receiver_cook)
	{
	}
	void Execute() const override
	{
		std::cout << "->The customer ordered a steak" << std::endl;
		this->receiver_cook_->DoFuncA(this->sum_);
		this->receiver_cook_->DoFuncB(this->weight_);
	}

private:
	std::shared_ptr<Receiver> receiver_cook_;
	int                       sum_    = 0;
	int                       weight_ = 0;
};
  • 通过中心来分配执行命令
/*饭店前台*/
class Invoker {
private:
	vector<std::shared_ptr<Command>> command_list_;

public:
	~Invoker() { command_list_.clear(); }
	void InsertFontCommand(std::shared_ptr<Command> command) { command_list_.insert(command_list_.begin(), command); }
	void PushBackCommand(std::shared_ptr<Command> command) { command_list_.push_back(command); }
	void ExecuteCommand()
	{
		std::cout << "The customer order start execute!" << std::endl;
		for (auto& item_command : command_list_) {
			item_command->Execute();
		}
		std::cout << "The customer order finished!" << std::endl;
	}
};
  • 创建用户命令并执行
int main()
{
	//饭店前台
	auto invoker            = std::make_shared<Invoker>();
	//创建厨师小明
	auto receiver_cook_user = std::make_shared<CookReceiver>("xiao ming");
	//订购牛排并指定小明厨师制作
	invoker->PushBackCommand(make_shared<SteakCommand>(receiver_cook_user, 5, 100));
	//订购牛奶
	invoker->InsertFontCommand(make_shared<MilkCommand>(5));
	//执行订单
	invoker->ExecuteCommand();
	return 0;
}

  • 输出结果如下
    在这里插入图片描述

命令模式的思考

优点:

  • 单一职责,实现了触发和执行的解耦操作;
  • 复合开闭原则,无需修改原有代码,就可增加新的命令
  • 可以把多个操作组合成一个复杂的命令,从而实现复杂的逻辑
  • 排队中的操作命令可以排序或撤销
  • 维护日志方便,更好的回溯操作

缺点:

  • 简单的逻辑套用命令模式,由于中间传递调用者的加入会变得复杂
  • 如果命令过多,很容易出现类数量膨胀的情况

总结:

  • 如果遇到复杂的问题,尤其是客户端这种,命令模式是一种很好的解耦UI和逻辑的设计方式。

命令模式与其他模式的比较

  • 命令在发送者和请求者之间建立单向连接

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

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

相关文章

Hudi(10):Hudi集成Spark之并发控制

目录 0. 相关文章链接 1. Hudi支持的并发控制 1.1. MVCC 1.2. OPTIMISTIC CONCURRENCY 2. 使用并发写方式 3. 使用Spark DataFrame并发写入 4. 使用Delta Streamer并发写入 0. 相关文章链接 Hudi文章汇总 1. Hudi支持的并发控制 1.1. MVCC Hudi的表操作&#xff0c;如…

阿里云 EDAS Java服务日志中打印调用链TraceId

最近要搭建阿里云的日志服务SLS&#xff0c;收集服务日志&#xff0c;进行统一的搜索查询。但遇到一个问题如何在日志中打印链路的TraceId&#xff0c;本文章记录一下对EDAS免费的解决方法。 先看一下阿里官方文档 业务日志关联调用链的TraceId信息 从文档上看&#xff0c;想要…

基于SSM的资源发布系统

项目介绍&#xff1a; 该系统基于SSM技术&#xff0c;数据层为MyBatis&#xff0c;数据库使用mysql&#xff0c;MVC模式&#xff0c;B/S架构&#xff0c;具有完整的业务逻辑。系统共分为管理员&#xff0c;用户两种角色&#xff0c;主要功能&#xff1a;登陆注册&#xff0c;用…

数据结构:跳表

文章目录跳表跳表的由来单链表的查找效率太低提高单链表的查找效率跳表的时间复杂度分析跳表的空间复杂度分析跳表的插入操作跳表的删除操作跳表索引动态更新跳表 对链表进行改造&#xff0c;在链表上加多级索引的结构就是跳表&#xff0c;使其可以支持类似“二分”的查找算法。…

Redis查询之RediSearch和RedisJSON讲解

文章目录1 Redis查询1.1 RedisMod介绍1.2 安装Redis1.3 RediSearchRedisJSON安装1.3.1 下载安装1.3.2 修改配置1.4 RedisJSON操作1.4.1 基本操作1.4.1.1 保存操作JSON.SET1.4.1.2 读取操作JSON.GET1.4.1.3 批量读取操作JSON.MGET1.4.1.4 删除操作JSON.DEL1.4.1.5 其他命令1.4.1…

鲲鹏Bigdata pro之Hive的基本操作(创建表、查询表)

1 介绍 本文主要依据《鲲鹏Bigdata pro之Hive集群部署》实验教程上的Hive操作例子讲解&#xff0c;方便大数据学员重用相应的操作语句。同时对实验过程中出现的问题给以解决方法&#xff0c;重现问题解决的过程。以让大家认识到&#xff0c;出现问题很正常&#xff1b;同时&am…

Java设计模式中接口隔离原则是什么?迪米特原则又是什么,啥又是合成复用原则,这些又怎么运用

继续整理记录这段时间来的收获&#xff0c;详细代码可在我的Gitee仓库SpringBoot克隆下载学习使用&#xff01; 3.5 接口隔离原则 3.5.1 特点 使用的类不应该被迫依赖于不想使用的方法&#xff0c;应该依赖接口方法 3.5.2 案例(安全门) 防火功能代码 public interface Fi…

第一章:统计学习方法概论

大纲1.1统计学习的特点1.2统计学习方法步骤1.3 统计学习的分类基本分类&#xff1a;1.4 监督学习方法的三要素模型&#xff1a;条件概率分布P(Y∣X)P(Y|X)P(Y∣X)或决策分布Yf(X)Yf(X)Yf(X)策略&#xff1a;在所有假设空间中选择一个最优模型注意事项&#xff1a;算法&#xff…

Java设计模式中适配器模式是什么/适配器模式可以干什么/又如何实现

继续整理记录这段时间来的收获&#xff0c;详细代码可在我的Gitee仓库SpringBoot克隆下载学习使用&#xff01; 5.3 适配器模式 5.3.1 概述 将一个类的接口转换为客户希望的另一种接口&#xff0c;使得原本由于接口不兼容而不能一起工作的那些类能一起工作分为类适配器模式和…

一套采用ASP.NET开发的工作通OA协同办公系统源码 流程审批 公文流转 文档管理

分享一套采用ASP.NET基于C#开发&#xff0c;使用桌面式的OA协同办公系统&#xff0c;超好用户体验效果的后台管理界面&#xff0c;集成 资讯、邮件、日程、文档&#xff08;在线文件档案管理&#xff09;、流程审批、公文流转、沟通与分享&#xff08;在线聊天和内部论坛&#…

基于LLVM的C编译器--lcc——以CLion用SSH连接WSL Ubuntu22.04为例

Windows 10 22H2CLion 2022.3.1Ubuntu 20.04 &#xff08;Microsoft Store内的WSL发行版&#xff09; 一、下载WSL&#xff0c;换源&#xff0c;切换到WSL2 1.1 保证windows版本 在设置->系统->关于中查看 必须是win10及以上对于x64系统&#xff1a;版本1903或更高版…

ArcGIS基础实验操作100例--实验63由图片创建点符号

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 高级编辑篇--实验63 由图片创建点符号 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff08;1&…

Java设计模式中代理模式是什么/JDK动态代理分为哪些,静态代理又怎么实现,又适合哪些场景

继续整理记录这段时间来的收获&#xff0c;详细代码可在我的Gitee仓库SpringBoot克隆下载学习使用&#xff01; 5.结构型模式 5.1 概述 根据如何将类或对象按某种布局组成更大的结构&#xff0c;分为类结构模式和对象结构模式&#xff0c;前者采用继承机制来组织接口和类&am…

视频序列对比学习

前言 视频embedding化也即表征有很多实际的应用场景&#xff0c;比如文本-视频 pair的检索等等。由于视频一般来说较长&#xff0c;所以对于给定的一段话&#xff0c;其中的某些sentence句子一般对应着视频中某几个clip片段&#xff0c;之前常规的做法都是去匹配所有的sentence…

人工服务、人工智能和分析是联络中心的主要趋势

数字联络中心提供商 IPI 宣布了其对 2023 年的预测。IPI 非常重视提供卓越的客户联系&#xff0c;认为未来一年将由以下趋势定义&#xff1a;专注于人工服务&#xff1b;增加对人工智能和自动化的采用&#xff1b;以及更多地使用数据和分析。 关注人性化服务 据 IPI 称&#…

实现QTreeView、QTableView子项中的复选框勾选/取消勾选功能

1.前言本博文所说的技术点适用于同时满足下面条件的所有视图类&#xff1a;模型类从 QAbstractItemModel派生。代理类从QStyledItemDelegate派生。故本博文所说的技术点也适用于QTableView。2.需求提出基于Qt的model/view framework技术&#xff0c;利用QTreeView树视图实现业务…

【异常】SpringSecurity登录失败:Full authentication is required to access this resource

一、报错提示 SpringSecurity提示如下内容&#xff1a; 2023-01-07 06:08:51.843 [cdi-ids-commonprovider] [http-nio-9092-exec-14] WARN com.desaysv.tsp.logic.ids.config.MyAuthenticationEntryPoint - 登录失败&#xff1a;Full authentication is required to acces…

基于Java+Jsp+SpringMVC漫威手办商城系统设计和实现

基于JavaJspSpringMVC漫威手办商城系统设计和实现 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java毕设项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取源码联…

2023 年值得关注的 7 大人工智能 (AI) 技术趋势

&#x1f482; 个人网站:【海拥】【摸鱼游戏】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 想寻找共同学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 人工智能 (AI) 已经接…

图数据库Neo4j实战(全网最详细教程)

1.图数据库Neo4j介绍 1.1 什么是图数据库&#xff08;graph database&#xff09; 随着社交、电商、金融、零售、物联网等行业的快速发展&#xff0c;现实社会织起了了一张庞大而复杂的关系网&#xff0c;传统数据库很难处理关系运算。大数据行业需要处理的数据之间的关系随数…