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. 需要支持可撤销操作的场景。

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

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

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

相关文章

almalinux centos8系统zlmediakit编译安装

脚本 # 安装依赖 gcc-c.x86_64 这个不加的话会有问题&#xff0c; cmake需要在线安装 sudo yum -y install gcc gcc-c libssl-dev libsdl-dev libavcodec-dev libavutil-dev ffmpeg git openssl-devel gcc-c.x86_64 cmake mkdir -p /home/zenglg cd /home/zenglg git clon…

【开箱即用】前后端同时开源!周末和AI用Go语言共同研发了一款笔记留言小程序!

大家好&#xff0c;我是豆小匠。 真的是当你在怀疑AI会不会取代人类的时候&#xff0c;别人已经用AI工具加速几倍的生产速度了… 周末体验了和AI共同开发的感受&#xff0c;小项目真的可以一人全干了… 本次实验使用的AI工具有两个&#xff1a;1. GitHub Copilot&#xff08;…

JVM运行时数据区域

文章目录 内存结构程序计数器&#xff08;寄存器&#xff09;虚拟机栈局部变量表两类异常状况 线程运行诊断 本地方法栈堆方法区运行时常量池串池&#xff08;StringTable&#xff09;字符串的拼接串池的位置StringTable垃圾回收StringTable性能调优 直接内存 内存结构 程序计…

blue beacon rssi 指纹室内定位数据集

数据集是开展实验的基础&#xff0c;搜集并分享。如果你有关于室内定位的问题&#xff0c;请联系博主。 namedatesetpapercommentBLEBeacon: A Real-Subject Trial Dataset from Mobile Bluetooth Low Energy Beaconshttps://github.com/dimisik/BLEBeacon-Datasethttps://arxi…

【云备份】业务处理

文章目录 1. 业务处理作用功能 2. 代码框架编写构造函数UpLoad ——文件上传请求ListShow —— 展示页面请求处理实现Download —— 下载请求的处理实现断点续传实现 1. 业务处理 作用 业务处理模块是对客户端的业务请求进行处理 功能 1.文件上传请求&#xff1a;备份客户端…

RK3568平台开发系列讲解(Linux系统篇)netlink 监听广播信息

** 🚀返回专栏总目录 文章目录 一、什么是netlink 机制二、netlink 的使用2.1、创建 socket2.2、绑定套接字2.3、接收数据沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将介绍如何通过 netlink 监听广播信息。 一、什么是netlink 机制 Netlink 是 Linux 内核中…

反序列化漏洞详解(一)

目录 一、php面向对象 二、类 2.1 类的定义 2.2 类的修饰符介绍 三、序列化 3.1 序列化的作用 3.2 序列化之后的表达方式/格式 ① 简单序列化 ② 数组序列化 ③ 对象序列化 ④ 私有修饰符序列化 ⑤ 保护修饰符序列化 ⑥ 成员属性调用对象 序列化 四、反序列化 …

Stream

什么是Stream&#xff1f; 也叫Stream流&#xff0c;是jdk8开始新增的一套API&#xff0c;可以用来操作集合或者数组的数据 优势&#xff1a;Stream流大量的结合了Lambda的语法风格来编程&#xff0c;提供了一种更加强大&#xff0c;更加简单的方式操作集合或数组中的数据&am…

CTF-虚拟机-QEMU-前置知识-操作流程与源码阅读

文章目录 总览内存PCI设备PCI配置空间前64个字节对应源码Memorry空间的BARIO空间的BAR MMIOPMIOIspci访问PCI设备配置空间中的Memory空间和IO空间MMIOPMIO QQM&#xff08;qemu object model&#xff09;简洁概要将 TypeInfo 注册 TypeImpl&#xff1a;ObjectClass的初始化&…

新款任务悬赏拉新地推本地任务同城地区定位游戏试玩任务联盟众人帮威客兼职任务墙

新款任务悬赏拉新地推本地任务同城地区定位游戏试玩任务联盟众人帮威客兼职任务墙 源码开源无任何加密及授权 后端采用PHPTinkCMF 前端采用UniappVUE 网页端双端APP可封装小程序可对接公众号登录 采用原生混合框架&#xff0c;拒绝卡顿。 https://download.csdn.net/downl…

文件操作--IO

目录 ♫什么是文件 ♫文件路径 ♫文件类型 ♫文件的管理 ♪File的构造方法 ♪File的常用方法 ♫文件的内容操作 ♪InputStream ♪OutputStream ♪字符流读写文件 ♫Scanner与流对象 ♫什么是文件 文件在计算机里可以指“狭义”的文件&#xff08;指硬盘上的文件和目录&…

第一百八十七回 DropdownButton组件

文章目录 1. 概念介绍2. 使用方法2.1 DropdownButton2.2 DropdownMenuItem 3. 示例代码4. 内容总结5. 经验分享 我们在 上一章回中介绍了"DropdownMenu组件"相关的内容&#xff0c;本章回中将介绍 DropdownButton组件.闲话休提&#xff0c;让我们一起Talk Flutter吧…

基于SpringBoot学生宿舍管理系统的设计与开发

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对学生宿舍信息管理混乱&#xff0c;出错率高&#xff0c;信息安全性差…

javaee实验:MVC 框架技术应用——URL 映射及方法参数的使用

目录 urlmvc框架mvc框架的设计mvc流程 实验目的实验内容实验过程创建项目创建项目结构编写代码简单测试一下 url 和 Hypertext 以及 HTTP 一样&#xff0c;URL 是 Web 中的一个核心概念。它是浏览器用来检索 web 上公布的任何资源的机制 URL 代表着是统一资源定位符&#xff…

OpenCV技术应用(6)— 暖色滤镜和冷色滤镜

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。本节课就手把手教大家如何将一幅图像转化成暖色滤镜和冷色滤镜&#xff0c;希望大家学习之后能够有所收获~&#xff01;&#x1f308; 目录 &#x1f680;1.技术介绍 &#x1f680;2.暖色滤镜 &#x1f680;3.冷色滤…

每日一练:阿姆斯特朗数

1. 概述 阿姆斯特朗数&#xff08;Armstrong number&#xff09;&#xff0c;也称为自恋数、自幂数&#xff08;narcissistic number&#xff09;、水仙花数&#xff0c;是指一个n位数&#xff08;n≥3&#xff09;&#xff0c;它的每个位上的数字的n次幂之和等于它本身。换句话…

AVFormatContext协议层:理论与实战

文章目录 前言一、协议操作对象结构二、初始化 AVIOContext 函数调用关系三、avio 实战 1&#xff1a;打开本地文件或网络直播流1、示例源码2、运行结果①、解决方法 1②、解决方法 2 四、avio 实战 2&#xff1a;自定义 AVIO1、示例源码2、运行结果 五、avio 实战 3&#xff1…

Vivado版本控制

Vivado版本控制 如果您有幸进入FPGA领域&#xff0c;那么会遇到版本控制问题&#xff0c;本文讲解的是如何用git进行Vivado进行版本控制。 搭建Git环境 一 首先需要一个git环境&#xff0c;并选择一个托管平台&#xff08;github,gitlab,gitee&#xff09; Git下载地址&…

【广州华锐视点】广东3D展厅开发服务找广州华锐视点,打造未来展览新体验!

随着科技的不断发展&#xff0c;人们对于信息获取和传播的方式也在不断创新。传统的实体展览馆在空间、时间、地域等方面存在诸多限制&#xff0c;而3D数字展厅则为我们提供了一个全新的解决方案。广州华锐互动致力于为客户提供专业的3D数字展厅定制开发服务&#xff0c;让您的…

滑动平均窗口的定义,优点,缺点,以及目前的应用!!

文章目录 前言一、滑动平均窗口的优点二、滑动平均窗口的缺点三、滑动平均窗口的应用 前言 滑动平均窗口是一种数据处理方法&#xff0c;它以固定的窗口大小对数据进行移动&#xff0c;并在每个窗口内计算数据的平均值。这种方法主要用于平滑数据&#xff0c;减小数据波动的影…