【AHK V2】设计模式之命令模式
目录
- 情景剧场
- 什么是命令模式
- 优缺点
- 优点
- 缺点
- 使用命令模式的步骤
- 命令模式代码示例
- 合理使用AI工具自动生成代码
情景剧场
我们来设想一个场景:
你进入一家餐馆,餐馆只有老板一个人(老板即厨师)。
“老板,一份小炒肉,不要辣。”
老板收到了你的订单请求,去后厨做菜了。这时又进来几位顾客:
“老板,来两份清炒时蔬,不要辣。”
“老板,我要一份清炒时蔬,多放辣。”
“老板,一份小炒肉,多放辣,打包。”
“老板,我的两份清炒时蔬改成一份,打包。”
…
当顾客变多,请求也变多,而每个顾客的请求也非常不一样。老板就很容易分不清谁的需求是什么,做错菜、上错菜都是会发生的错误。顾客对老板直接提出请求,请求多了很容易导致混乱。这里顾客就是请求的发送者,老板就是请求的接收者,请求者和接收者的“紧耦合”虽然逻辑简单,但是很容易僵化。
当给餐馆加上服务员和订单,就会不一样:
顾客走进餐馆开始点单,服务员接过顾客的订单,并将其写在一张纸上。服务员去厨房,把订单贴在墙上,订单按排列顺序到达厨师手中,这样厨师做菜就不会混乱,也不会遗忘。厨师将餐点与订单一起转交服务员,服务员检查订单并将所有东西带到顾客的餐桌上。在此期间,顾客可以撤销订单或增删订单需求。
顾客不需要知道是谁来完成烹饪,厨师不需要知道是谁的订单,纸质订单用作命令,一直排在队列中。这也就实现了请求者和接收者的解耦。
什么是命令模式
命令模式(Command Pattern)是一种行为设计模式,它把请求或操作封装成一个包含有关请求所有信息的独立对象,此转换允许将请求作为方法参数传递,延迟或排队请求的执行,并支持可撤消的操作,从而实现将请求者和接收者解耦。
优缺点
命令模式是一种灵活且功能强大的设计模式,主要优点是它允许在不修改现有客户端代码的情况下添加新的命令。此外,通过使用命令模式,可以将操作记录到日志中、撤销操作或者将操作进行队列化等,同时他也有一些缺点。
优点
-
解耦性:命令模式通过将请求发送者与接收者解耦,使得请求发送者不需要知道接收者的具体实现细节,从而增强了系统的灵活性和可维护性。
-
可扩展性:通过添加新的具体命令类,可以很容易地扩展系统的功能,而不需要修改已有的代码。
-
支持撤销和重做:命令模式可以记录请求的历史操作,从而支持对操作的撤销和重做,提供了更好的用户体验。
-
支持日志和队列:可以将命令对象保存在日志中,实现系统的日志记录功能。此外,命令对象还可以组织成队列,实现命令的批处理和延迟执行。
-
命令模式符合“开-闭”原则。因为将具体命令封装成了一个一个独立的对象,所有当需要修改现有功能时,可以通过添加新代码来实现,而不是修改已有的代码。这样可以提高代码的可维护性和可扩展性,减少出错率和代码复杂度。具体点说,在增加新的具体命令或增加命令的接收者时,不需要修改原有调用者的代码;而在增加新的调用者时,不需要修改原有的具体命令和接收者的代码。
-
命令模式支持宏命令。
即将多个命令组合成一个命令。这样可以将多个操作封装成一个操作,减少了代码的冗余和重复,提高代码的复用率。
缺点
- 类的数量增加:引入命令模式会增加系统中的类的数量,特别是在有大量具体命令类的情况下,可能会导致类的数量激增,增加了系统的复杂性。
- 命令的单一性:每个具体命令类通常只封装了一个特定的操作,这可能会导致系统中存在大量的具体命令类,增加了系统的管理和维护成本。
- 对象间的调用链可能过长:在命令模式中,请求发送者、命令对象、接收者之间可能存在多层的调用链,特别是在复杂的系统中,可能会导致调用链过长,影响系统的性能。
虽然命令模式有一些缺点,但在很多场景下仍然是一种非常有用的设计模式,特别是在需要支持撤销、重做、日志记录和队列等功能的情况下。
使用命令模式的步骤
使用命令模式可以通过以下步骤进行:
- 确定参与者:首先,确定在系统中谁是命令的发起者(Invoker)、命令的接收者(Receiver)、以及具体的命令对象(Command)。
- 定义命令接口:创建一个命令接口,其中包含一个执行操作的方法(如execute())。这个接口可以是抽象类或者接口,具体取决于设计的需求。
- 实现具体命令类:针对每个具体的操作,创建一个具体的命令类,实现命令接口,并在其中封装具体的操作实现。
- 创建接收者类:定义接收者类,实现命令所需的具体操作。 创建调用者类:创建一个调用者类,负责向具体的命令对象发送请求。
- 创建客户端代码:在客户端代码中创建具体的命令对象,并将其关联到调用者对象上。
命令模式代码示例
; 定义命令接口
class ICommand {Execute() {; 需要被覆盖的方法(抽象方法)}
}; 定义具体命令A
class CommandA extends ICommand {Execute() {MsgBox("Command A Executed")}
}; 定义具体命令B
class CommandB extends ICommand {Execute() {MsgBox("Command B Executed")}
}; 定义调用者,负责执行命令
class Invoker {__New(command) {this.command := command}ExecuteCommand() {this.command.Execute()}
}; 客户端代码
main() {; 创建命令实例_commandA := CommandA()_commandB := CommandB(); 创建调用者并关联命令_invokerA := Invoker(_commandA)_invokerB := Invoker(_commandB); 执行命令_invokerA.ExecuteCommand()_invokerB.ExecuteCommand()
}; 运行主程序
main()
合理使用AI工具自动生成代码
上面的代码是用Comate生成的
代码就是上面那部分,我就不截图了,稍微改改就可以运行。也可以把报错信息提示给它,它会给出修改代码示例。
还可以让它输出UML类图:
这个mermaid代码直接在CSDN的波纹MD编辑模式可以直接用哦。
感兴趣可以在VSCODE中安装这个AI编码助手——Comate,感觉能在小众语言AHK上表现这么好还是很令人惊讶的。
相关文章:

【AHK V2】设计模式之命令模式
目录 情景剧场什么是命令模式优缺点优点缺点 使用命令模式的步骤命令模式代码示例合理使用AI工具自动生成代码 情景剧场 我们来设想一个场景: 你进入一家餐馆,餐馆只有老板一个人(老板即厨师)。 “老板,一份小炒肉&am…...

2024年5月20日 (周二) 叶子游戏新闻
《边境之塔》登陆Steam 复古风恐怖生存冒险DascuMaru制作并发行,一款低像素3D复古风恐怖生存冒险新游《边境之塔(The Tower on the Borderland)》登陆Steam正式推出,限时九折优惠,本作暂不支持中文。 勇魅出击…...

【SQL学习进阶】从入门到高级应用(二)
文章目录 简单查询查一个字段查多个字段查所有字段查询时字段可参与数学运算查询时字段可起别名as关键字省略as关键字别名中有空格别名中有中文 🌈你好呀!我是 山顶风景独好 💝欢迎来到我的博客,很高兴能够在这里和您见面…...

FL Studio v21.2.3.4004中文破解版百度网盘下载
FL Studio v21.2.3.4004中文破解版是一款完整的软件音乐制作环境或数字音频工作站 (DAW)。代表了超过 18 年的创新发展,它在一个软件包中提供了您创作、编曲、录制、编辑、混音和掌握专业品质音乐所需的一切。FL Studio v21.2.3.4004中文破解版现在是世界上最受欢迎…...

从0开始写一个环境保护网站的第3天(JAVAWEB)
1.目标 实现首页的环境保护原因的查询,和底部友情连接部分 2.实现 2.1建立数据库表格(这里数据全是百度查询) 环境保护原因表: 友情连接表:(数据来源https://zhuanlan.zhihu.com/p/696243646࿰…...

Java中volatile关键字
保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的,volatile关键字会强制将修改的值立即写入主存。 1.volatile的可见性 一个典型的例子:永不停止的循环。 public class Forever…...

医院挂号就诊系统的设计与实现
前端使用Vue.js 后端使用SpiringBoot MyBatis 数据使用MySQL 需要项目和论文加企鹅:2583550535 医院挂号就诊系统的设计与实现_哔哩哔哩_bilibili 随着社会的发展,医疗资源分布不均,患者就诊难、排队时间长等问题日益突出,传统的…...

SpringBoot整合RabbitMQ的快速使用教程
目录 一、引入依赖 二、配置rabbitmq的连接信息等 1、生产者配置 2、消费者配置 三、设置消息转换器 四、生产者代码示例 1、配置交换机和队列信息 2、生产消息代码 五、消费者代码示例 1、消费层代码 2、业务层代码 在分布式系统中,消息队列是一种重要…...

pytorch比较操作
文章目录 常用的比较操作1.torch.allclose()2.torch.argsort()3.torch.eq()4.torch.equal()5.torch.greater_equal()6.torch.gt()7.torch.isclose()8.torch.isfinite()9.torch.isif()10.torch.isposinf()11.torch.isneginf()12.torch.isnan()13.torch.kthvalue()14.torch.less_…...

2024年4月—马克思主义基本原理概论真题及答案解析(上海自考)
目录 1.选择题 2.简答题 3.论述题 1.选择题 2.简答题...

「Element-UI表头添加带Icon的提示信息」
一、封装全局组件 🍓 注意:可以直接复制该文件 <!-- // 写一个PromptMessage的组件,并全局注册 --> <template><div class"tooltip"><el-tooltip effect"dark" placement"right">&l…...

单细胞 10X 和seurat对象学习
单细胞seurat数据的基础知识 rm(list ls()) library(Seurat) #注意这个报错 #Warning: Feature names cannot have underscores (_), replacing with dashes (-) folderslist.files(./,pattern[123]$) folders scList lapply(folders,function(folder){ CreateSeuratObject(…...

Flutter 中的 Flex 小部件:全面指南
Flutter 中的 Flex 小部件:全面指南 Flutter 的布局系统非常灵活,允许开发者以声明式的方式构建复杂的用户界面。Flex 是 Flutter 中用于创建灵活布局的核心小部件之一,它提供了水平和垂直的线性布局能力。本文将详细介绍 Flex 小部件的使用…...

统计每个活动的用户访问量,且每个用户仅统计一次
场景:统计每个活动的用户访问量,且每个用户仅统计一次。 首先活动表是已经存在了的,一般情况下,我们都会在创建一个用户访问表,其中唯一主键是用户ID活动ID作为唯一主键 create table user_visist_activity_record(i…...

基于SpringBoot的本科生考研率统计系统
基于SpringBoot的本科生考研率统计系统 一、开发技术二、功能模块三、代码结构四、数据库设计五、运行截图六、源码获取 一、开发技术 技术:SpringBoot、MyBatis-Plus、Redis、MySQL、Thymeleaf、Html、Vue、Element-ui。 框架:基于开源框架easy-admin开…...

JMeter正则表达式提取器和JSON提取器基础用法,小白必会!
最近在利用JMeter做接口自动化测试,正则表达式提取器和JSON提取器用的还挺多,想着分享下,希望对大家的接口自动化测试项目有所启发。 在 JMeter 中,正则表达式和 JSON 提取器都是用于从响应数据中提取所需内容,但它们…...

5-26作业
网络聊天室 服务器: 1 #include <myhead.h>2 int main(int argc, const char *argv[])3 {4 if(argc!3)5 {6 printf("请输入IP和端口号\n");7 return -1;8 }9 int sfd socket(AF_INET, SOCK_DGRAM, 0);10 if(…...

2024.05.28学习记录
1. 小林coding 计网复习 2.代码随想录刷题. 图论.和复习数组.链表 3.rosebush完成select组件...

撤销最近一次的提交,使用git revert 和 git reset的区别
文章目录 工作区 暂存区 本地仓库 远程仓库需求:已推送到远程仓库,想要撤销操作git revert (添加新的提交来“反做”之前的更改,云端会残留上次的提交记录)git reset(相当于覆盖上次的提交)1.--…...

MySQL详细安装、配置过程,多图,详解
本文适合centos7环境下安装mysql,在安装和卸载过程中,都在root用户下完成。文章目录 清理环境获取mysql官方yum源安装mysql yum源安装mysql服务安装报错解决办法验证是否安装完成启动mysql服务登录服务方法一:方法二:方法三&#…...

音视频学习规划
文章目录 概述闲聊点 小结 概述 最近在学习音视频,觉得还是要先写个提纲,给自己制定下学习路线及目标。先写下我的个人流程及思路。 ffmpeg的命令ffmpeg api播放器流媒体RTMP,HLS 闲聊点 先说下学习命令行吧,学习命令行是为了…...

代码随想录算法训练营第21天|● 530.二叉搜索树的最小绝对差 ● 501.二叉搜索树中的众数 ● 236. 二叉树的最近公共祖先
二叉搜索树的最小绝对差 题目连接 https://leetcode.cn/problems/minimum-absolute-difference-in-bst/ 思路: 利用二叉搜索树的中序遍历的特性,将二叉树转成有序数组,进而求任意两个数的最小绝对差。 代码 /*** Definition for a bina…...

K8S中Prometheus+Grafana监控
1.介绍 phometheus:当前一套非常流行的开源监控和报警系统。 运行原理:通过HTTP协议周期性抓取被监控组件的状态。输出被监控组件信息的HTTP接口称为exporter。 常用组件大部分都有exporter可以直接使用,比如haproxy,nginx,Mysql,Linux系统信…...

题解:CF1968F(Equal XOR Segments)
题解:CF1968F(Equal XOR Segments) 题目翻译:定义一个序列是好,当且仅当可以将其分成大于 1 1 1 份,使得每个部分的异或和相等。现在给定一个长度为 n n n 的序列 a a a,以及 q q q 次查询…...

Python操作MySQL实战
文章导读 本文用于巩固Pymysql操作MySQL与MySQL操作的知识点,实现一个简易的音乐播放器,拟实现的功能包括:用户登录,窗口显示,加载本地音乐,加入和删除播放列表,播放音乐。 点击此处获取参考源…...

【Linux系统】进程间通信
本篇博客整理了进程间通信的方式管道、 system V IPC的原理,结合大量的系统调用接口,和代码示例,旨在让读者透过进程间通信去体会操作系统的设计思想和管理手段。 目录 一、进程间通信 二、管道 1.匿名管道 1.1-通信原理 1.2-系统调用 …...

北大国际医院腹膜后纤维化课题组 多学科协作开辟治疗新径
腹膜后纤维化(Retroperitoneal Fibrosis,简称RPF)是一种罕见的自身免疫性疾病,其核心特征是纤维组织的异常增生与硬化。这种疾病主要影响肾脏下方的腹主动脉和髂动脉区域,增生的纤维组织会逐渐压迫周围的输尿管和下腔静脉,从而导致一系列并发症,包括主动脉瘤、肾功能衰竭等,甚至…...

面试数据库八股文十问十答第七期
面试数据库八股文十问十答第七期 作者:程序员小白条,个人博客 相信看了本文后,对你的面试是有一定帮助的!关注专栏后就能收到持续更新! ⭐点赞⭐收藏⭐不迷路!⭐ 1)索引是越多越好吗ÿ…...

【C++题解】1133. 字符串的反码
问题:1133. 字符串的反码 类型:字符串 题目描述: 一个二进制数,将其每一位取反,称之为这个数的反码。下面我们定义一个字符的反码。 如果这是一个小写字符,则它和字符 a 的距离与它的反码和字符 z 的距离…...

【Python编程实战】基于Python语言实现学生信息管理系统
🎩 欢迎来到技术探索的奇幻世界👨💻 📜 个人主页:一伦明悦-CSDN博客 ✍🏻 作者简介: C软件开发、Python机器学习爱好者 🗣️ 互动与支持:💬评论 &…...