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

news2024/12/23 19:58:56

命令者模式是一个高内聚的模式, 其定义为: 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.coloradmin.cn/o/1277742.html

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

相关文章

非得让你会之MyBatis插件与Java动态代理

引言 咱们今天聊聊Java动态代理&#xff0c;这东西在开发中真的太常见了。比如Spring AOP、RPC&#xff0c;它们都离不开动态代理。然后&#xff0c;咱们再来说说MyBatis插件&#xff0c;这可是MyBatis框架中的一个超实用的功能&#xff0c;它就像是给MyBatis加了个“超能力”…

卷积的理解,卷积与通道的关系

神经网络中的卷积操作卷积在图像领域的功能单通道卷积多通道卷积&#xff08;1个卷积核&#xff09;多通道卷积&#xff08;多个卷积核&#xff09;总结扩展 图像处理中的卷积核恒等&#xff08;Identity&#xff09;边缘检测&#xff08;Edge detection&#xff09;锐化&#…

2243:Knight Moves

文章目录 题目描述思路1. DFS2. BFS3. 动态规划 解题方法1. DFS2. BFS3. 动态规划 题目描述 题目链接 翻译如下&#xff1a; 注&#xff1a;骑士移动是和象棋里的马一样走的是日字型 你的一个朋友正在研究旅行骑士问题 &#xff08;TKP&#xff09;&#xff0c;你要找到最短的…

java学习part28线程安全Lock锁方式

138-多线程-线程安全的懒汉式_死锁_ReentrantLock的使用_哔哩哔哩_bilibili 1.lock类变量 2.使用方法 和以前的加锁一样&#xff0c;同步代码前加锁&#xff0c;代码后解锁&#xff0c;就表示锁住了这一块代码。 lock是上面声明的静态常量 3.同步和加锁对比

通义千问 模型学习 和 SDK试用

通义千问-14B-Chat-Int4 模型库 (modelscope.cn) **通义千问-14B&#xff08;Qwen-14B&#xff09;**是阿里云研发的通义千问大模型系列的140亿参数规模的模型。Qwen-14B是基于Transformer的大语言模型, 在超大规模的预训练数据上进行训练得到。预训练数据类型多样&#xff0…

2023年第十二届数学建模国际赛小美赛C题雪崩防范求解分析

2023年第十二届数学建模国际赛小美赛 C题 雪崩防范 原题再现&#xff1a; 雪崩是极其危险的现象。现在&#xff0c;我们对雪崩是如何形成的已经有了很好的理解&#xff0c;但是我们还不能详细地预测雪崩发生的原因、时间和地点。村庄和道路可以通过各种方式防止雪崩。避免在脆…

python datetime 获取特定一天的后一天或者后几天

这里写自定义目录标题 1 获取特定天的时间对象 具体时间格式参考&#xff1a;Python time strptime()和strftime()-CSDN博客 import datetimetimer datetime.datetime.strptime(date, "%Y-%m-%d")2 获取下一天或者【下x天】的数据并进行格式转换 # 下一天数据 ne…

编译原理:设计与实现一个简单词法分析器

设计与实现一个简单词法分析。具体内容是产生一个二元式文本文件&#xff0c;扩展名为dyd&#xff0c;可将Java或C程序(测试程序)分解成为一个一个的单词及类型。 &#xff08;选做&#xff1a;并查“单词符号与种别对照表”得出其种别&#xff0c;用一数字表示。&#xff09;…

Redis数据结构之压缩列表

压缩列表是Redis为节约内存而开发的&#xff0c;是由一系列特殊编码的连续内存块组成的顺序型数据结构。一个压缩列表可以包含任意多个节点&#xff0c;每个节点可以保存一个字节数组或者整数值。 压缩列表构成 zlbytes: 记录整个压缩列表占用的内存字节数&#xff0c;对压缩列…

【每日一题】1094. 拼车-2023.12.2

题目&#xff1a; 1094. 拼车 车上最初有 capacity 个空座位。车 只能 向一个方向行驶&#xff08;也就是说&#xff0c;不允许掉头或改变方向&#xff09; 给定整数 capacity 和一个数组 trips , trip[i] [numPassengersi, fromi, toi] 表示第 i 次旅行有 numPassengersi…

Android 缩减、混淆处理和优化应用

为了尽可能减小应用的大小&#xff0c;您应在发布 build 中启用缩减功能来移除不使用的代码和资源。启用缩减功能后&#xff0c;您还会受益于两项功能&#xff0c;一项是混淆处理功能&#xff0c;该功能会缩短应用的类和成员的名称&#xff1b;另一项是优化功能&#xff0c;该功…

eclipse中设置自动补齐代码

eclipse中设置自动补齐代码 01 在window里找到preference 02 在preference里搜索content assist 03 在Java的content assist设置 设置为.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 04 apply and close即可

PyLMKit(3):基于角色扮演的应用案例

角色扮演应用案例RolePlay 0.项目信息 日期&#xff1a; 2023-12-2作者&#xff1a;小知课题: 通过设置角色模板并结合在线搜索、记忆和知识库功能&#xff0c;实现典型的对话应用功能。这个功能是大模型应用的基础功能&#xff0c;在后续其它RAG等功能中都会用到这个功能。功…

Linux基础项目开发1:量产工具——UI系统(五)

前言&#xff1a; 前面我们已经把显示系统、输入系统、文字系统搭建好了&#xff0c;现在我们就要给它实现按钮操作了&#xff0c;也就是搭建UI系统&#xff0c;下面让我们一起实现UI系统的搭建吧 目录 一、按钮数据结构抽象 ui.h 二、按键编程 1.button.c 2.disp_manager…

赤峰学院师资培养管理系统的设计与实现

摘 要 随着我国国民经济建设的蓬勃发展和信息技术的越发成熟&#xff0c;各个行业都在积极使用现代化的管理工具&#xff0c;不断改善企业的服务质量&#xff0c;提高工作效率。对师资培养进行现代化的管理&#xff0c;提高工作效率是师资培养管理系统的一大优点。本文是一篇关…

Aspice(Automotive Software Process Improvement and Capability Determination)

Aspice&#xff08;Automotive Software Process Improvement and Capability Determination&#xff09; 1. 引言&#xff1a;ASPICE概述 定义 ASPICE简介&#xff1a;ASPICE&#xff08;Automotive Software Process Improvement and Capability Determination&#xff09;…

Qt Creator 11.0.3同时使用Qt6.5和Qt5.14.2

Qt Creator 11.0.3同时使用Qt6.5和Qt5.14.2 概要方法1.打开Qt Creator中的Kit&#xff0c;这里我直接附上几张截图&#xff0c;不同的版本打开位置可能有所不同&#xff0c;总之最终目的是要打开构建套件&#xff08;Kit&#xff09;2.可以看到构建套件里面有包含了“构建套件K…

栈顺序存储的实现(详解)

栈是一种数据结构&#xff0c;它具有后进先出&#xff08;LIFO&#xff09;的特性。栈可以用来存储一组元素&#xff0c;并且只能在栈顶进行插入和删除操作。栈的基本概念包括&#xff1a; 1. 入栈&#xff08;push&#xff09;&#xff1a;将元素添加到栈顶的操作。 2. 出栈&…

【halcon】C# halcon 内存暴增

1 读取图片需要及时手动释放 一个6M的图片通过halcon进行加载&#xff0c;大约会消耗200M的内存&#xff0c;如果等待GC回收&#xff0c;而你又在不停的读取图片&#xff0c;你的内存占用&#xff0c;将在短时间内飙升。 2 halcon控件显示图片需要清空。 /// <summary>…

Motion 5 for Mac,释放创意,打造精彩视频特效!

Motion 5 for Mac是一款强大的视频后期特效处理软件&#xff0c;为Mac用户提供了无限的创意可能性。无论你是专业的影视制作人&#xff0c;还是想为个人视频添加独特特效的爱好者&#xff0c;Motion 5都能满足你的需求&#xff0c;让你的视频脱颖而出。 Motion 5提供了丰富多样…