09-命令者模式-C语言实现

命令者模式是一个高内聚的模式, 其定义为: Encapsulate a request as an object,thereby letting you parameterize clients with different requests,queue or log requests,and support undoable operations.(将一个请求封装成一个对象, 从而让你使用不同的请求把客户端参数化, 对请求排队或者记录请求日志, 可以提供命令的撤销和恢复功能。 )

UML图:

代码实现:

#include <stdio.h>
#include <stdlib.h>// 命令接口
typedef struct {void (*execute)(void*);void (*undo)(void*);
} Command;// 具体命令类
typedef struct {Command command;void* receiver;void (*action)(void*);void (*undoAction)(void*);
} ConcreteCommand;void ConcreteCommand_execute(void* obj) {ConcreteCommand* self = (ConcreteCommand*)obj;self->action(self->receiver);
}void ConcreteCommand_undo(void* obj) {ConcreteCommand* self = (ConcreteCommand*)obj;self->undoAction(self->receiver);
}ConcreteCommand createConcreteCommand(void* receiver, void (*action)(void*), void (*undoAction)(void*)) {ConcreteCommand command;command.command.execute = ConcreteCommand_execute;command.command.undo = ConcreteCommand_undo;command.receiver = receiver;command.action = action;command.undoAction = undoAction;return command;
}// 调用者类
typedef struct {Command* command;void (*setCommand)(void*, Command*);void (*executeCommand)(void*);void (*undoCommand)(void*);
} Invoker;void Invoker_setCommand(void* obj, Command* command) {Invoker* self = (Invoker*)obj;self->command = command;
}void Invoker_executeCommand(void* obj) {Invoker* self = (Invoker*)obj;self->command->execute(self->command);
}void Invoker_undoCommand(void* obj) {Invoker* self = (Invoker*)obj;self->command->undo(self->command);
}Invoker createInvoker() {Invoker invoker;invoker.setCommand = Invoker_setCommand;invoker.executeCommand = Invoker_executeCommand;invoker.undoCommand = Invoker_undoCommand;return invoker;
}// 接收者类
typedef struct {void (*action)(void*);void (*undoAction)(void*);
} Receiver;void Receiver_action(void* obj) {printf("Receiver performs action.\n");
}void Receiver_undoAction(void* obj) {printf("Receiver undoes action.\n");
}Receiver createReceiver() {Receiver receiver;receiver.action = Receiver_action;receiver.undoAction = Receiver_undoAction;return receiver;
}int main() {Receiver receiver = createReceiver();ConcreteCommand command = createConcreteCommand(&receiver, &receiver.action, &receiver.undoAction);Invoker invoker = createInvoker();invoker.setCommand(&invoker, &command);invoker.executeCommand(&invoker);invoker.undoCommand(&invoker);return 0;
}

在上面的示例代码中,定义了命令接口Command和具体命令类ConcreteCommand,实现了执行和撤销方法来处理具体的命令。

同时还定义了调用者类Invoker,具有设置命令、执行命令和撤销命令的方法,并通过命令对象来调用相应的方法。

还定义了接收者类Receiver,具有执行操作和撤销操作的方法。

main函数中,首先创建了一个接收者对象receiver,然后创建了一个具体命令对象command,并将接收者对象和相应的操作方法传入。

接着创建了一个调用者对象invoker,通过调用者对象设置命令对象,并执行和撤销命令。

命令模式的优点:

  1. 可以将请求发送者与接收者解耦,使得请求发送者不需要知道具体的接收者和处理方法。

  2. 可以实现请求的参数化、队列化和记录日志等功能。

  3. 支持可撤销操作,可以随时撤销执行过的命令。

命令模式的缺点:

  1. 可能导致命令类的数量增加,因为每个具体命令都需要实现一个命令类。

  2. 可能引入额外的开销,因为需要维护命令对象和命令队列。

适用场景:

  1. 需要将请求发送者和接收者解耦的场景。

  2. 需要支持请求的参数化、队列化和记录日志等功能的场景。

  3. 需要支持可撤销操作的场景。

总结:命令模式通过将请求封装成对象来实现请求的参数化、队列化和记录日志等功能,并且支持可撤销操作。它可以降低系统的耦合度,提高系统的灵活性和可维护性。

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

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

相关文章

记录 | mac双屏时程序坞跑到副屏的解决方法

mac双屏时程序坞跑到副屏的解决方法&#xff1a; (1) 按下 optioncommandD&#xff0c;开启程序坞 “自动隐藏”&#xff0c;副屏程序坞消失&#xff1b; (2) 鼠标回到主屏&#xff0c;放在主屏正下方中间的边缘不要动&#xff0c;主屏能看到扩展坞出现了&#xff1b; (3) 按…

JDK17的安装与配置

JDK17的安装与配置 下载地址安装步骤配置环境变量验证安装是否成功 下载地址 此jdk17安装的系统是win10系统 https://www.oracle.com/java/technologies/downloads/ 这里选择JDK17进行下载 下载完成之后&#xff0c;显示如下图&#xff1a; 安装步骤 自定义的安装路径&…

测试:测试设计方法

一、等价类划分 等价类划分是一种软件测试方法&#xff0c;它将程序的输入域划分成若干部分&#xff08;子集&#xff09;&#xff0c;然后从每个子集中选取具有代表性的数据作为测试用例。等价类划分旨在确保测试用例的完整性和代表性&#xff0c;同时避免冗余测试。 等价类划…

智能优化算法应用:基于探路者算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于探路者算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于探路者算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.探路者算法4.实验参数设定5.算法结果6.参考文献7.…

动态规划------方法汇总

核心&#xff1a; 状态定义 状态转移方程 启发思路&#xff08;两种情况&#xff09;&#xff1a;选 或 不选 / 选哪个 DP三步&#xff1a;先写回溯&#xff0c;时间复杂度 指数级别&#xff1b;递归的过程中会重复计算&#xff0c;要保存计算结果&#xff0c;递归搜索…

Windows微软常用运行库合集2023

微软常用运行库合集适用于Windows系统的运行库合集包&#xff0c;基于微软官方的运行库而制作的&#xff0c;包括了常用的vb&#xff0c;vc2005/2008/2010/2012/2013/2017/2019/2005-2022&#xff0c;Microsoft Universal C Runtime&#xff0c;VS 2010 Tools For Office Runti…

Programming Contest 2023(AtCoder Beginner Contest 331)D题 Tile Pattern --- 题解

目录 D - Tile Pattern 题目大意&#xff1a; 思路&#xff1a; 代码&#xff1a; D - Tile Pattern D - Tile Pattern (atcoder.jp) 题目大意&#xff1a; 给你一个n和q&#xff0c;n为局部棋盘大小(n*n) 并且给出局部棋盘中黑白子位置的放置情况&#xff0c;q为查询次数…

SQL 错误 [1476] [22012]: ORA-01476: 除数为 0

Oracle sql 语句 添加判断&#xff0c;如果分母为0&#xff0c;则查询结果为0&#xff0c;如果分母不为0&#xff0c;则返回查询结果 你可以使用条件表达式来实现这个要求。以下是一个示例的Oracle SQL查询语句&#xff0c;其中添加了判断条件来处理分母为0的情况&#xff1a;…

微信小程序实现下拉刷新事件、上拉触底事件

通过Page页面事件监听下拉刷新事件、上拉触底事件 xxx.json {"enablePullDownRefresh": false,"onReachBottomDistance": 200 }xxx.js Page({.../*** page 绑定的下拉刷新* 页面下拉刷新事件的处理函数*/onPullDownRefresh: function () {console.log(&…

某60区块链安全之Create2实战一学习记录

区块链安全 文章目录 区块链安全Create2实战一实验目的实验环境实验工具实验原理实验内容Create2实战一 实验步骤分析合约源代码漏洞Create2实战一 实验目的 学会使用python3的web3模块 学会分析以太坊智能合约Create2引发的漏洞及其利用 找到合约漏洞进行分析并形成利用 实…

淘宝/天猫商品详情API接口丨京东商品详情丨1688商品详情丨接口key密钥获取方式

要获取淘宝/天猫商品详情API接口、京东商品详情API接口、1688商品详情API接口以及接口密钥&#xff08;Key&#xff09;&#xff0c;可以按照以下步骤进行操作&#xff1a; 注册并登录淘宝/天猫开发者中心或京东开放平台或1688开放平台&#xff0c;并创建应用。在创建应用的过…

GODOC命令无效,原因是需要手动安装

在看《GO程序设计语言》这本书&#xff0c;按照其中的内容&#xff0c;想看下GO自带的包的文档。 书中讲&#xff0c;可以直接输入GoDOC命令来打开一个服务器&#xff0c;从而可以用浏览器访问文档库。输入命令后&#xff0c;系统提示找不到该命令。 查了资料后才发现&#xff…

6-55.汽车类的继承

根据给定的汽车类vehicle&#xff08;包含的数据成员有车轮个数wheels和车重weight&#xff09;声明&#xff0c;完成其中成员函数的定义&#xff0c;之后再定义其派生类并完成测试。 小车类car是它的派生类&#xff0c;其中包含载人数passenger_load。每个类都有相关数据的输出…

解决Wireshark分析RTMP抓包时Unknown问题

使用Wireshark抓包时&#xff0c;经常出现很多Unknown包&#xff0c;但实际上的字节流实际是正常的。 其实&#xff0c;RTMPT设置里有一个最大包大小的设置&#xff0c;默认是32768&#xff0c;而且默认RTMPT协议配置了从多个TCP流中重组RTMPT的功能(应当是考虑基于HTTP的传输…

Redis RDB

基于内存的 Redis, 数据都是存储在内存中的。 那么如果重启的话, 数据就会丢失。 为了解决这个问题, Redis 提供了 2 种数据持久化的方案: RDB 和 AOF。 RDB 是 Redis 默认的持久化方案。当满足一定条件的时候, 会把当前内存中的数据写入磁盘, 生成一个快照文件 dump.rdb。Redi…

Doris 数据导入三:Routine Load 方式

例行导入(Routine Load)功能为用户提供了一种自动从指定数据源进行数据导入的功能。 1 适用场景 当前仅支持从Kafka系统进行例行导入,使用限制: (1)支持无认证的Kafka访问,以及通过SSL方式认证的Kafka集群。 (2)支持的消息格式为 csv, json 文本格式。csv 每一个 mess…

acwing算法基础之时空复杂度分析

目录 1 基础知识2 模板3 工程化 1 基础知识 &#xff08;一&#xff09; 由数据范围反推算法。 C中题目给出的要求时间是1秒或2秒计算出结果&#xff0c;而1秒内C可以执行 1 0 7 ∼ 1 0 8 10^7 \sim 10^8 107∼108次操作。故需要把时间复杂度控制在 1 0 8 10^8 108以内。 给…

Day48力扣打卡

打卡记录 最大化城市的最小电量&#xff08;二分前缀和差分数组贪心&#xff09; 链接 class Solution:def maxPower(self, stations: List[int], r: int, k: int) -> int:n len(stations)sum list(accumulate(stations, initial0))for i in range(n):stations[i] sum[…

vscode插件离线下载

离线下载插件地址&#xff1a;https://marketplace.visualstudio.com/VSCode

elasticsearch 内网下如何以离线的方式上传任意的huggingFace上的NLP模型(国内闭坑指南)

es自2020年的8.x版本以来&#xff0c;就提供了机器学习的能力。我们可以使用es官方提供的工具eland&#xff0c;将hugging face上的NLP模型&#xff0c;上传到es集群中。利用es的机器学习模块&#xff0c;来运维部署管理模型。配合es的管道处理&#xff0c;来更加便捷的处理数据…