命令模式(Command)
命令模式是一种行为设计模式,可将一个请求封装为一个对象,用不同的请求将方法参数化,从而实现延迟请求执行或将其放入队列中或记录请求日志,以及支持可撤销操作。其别名为动作(Action)模式或事务(Transaction)模式。
Command is a behavior design pattern, which can encapsulate a request as an object, parameterize the method with
different requests, so as to delay the execution of the request or put it in the queue or record the request log,
and support revocable operations.
结构设计
命令模式包含如下角色:
Command,命令基类,声明一个执行命令的接口。
ConcreteCommand,具体命令类,实现各种类型的请求。具体命令自身并不完成工作,而是会将调用委派给一个业务逻辑对象(Receiver)。但为了简化代码,这些类可以进行合并。
Invoker,调用者,负责对请求进行初始化,其中必须包含一个成员变量来存储对于命令对象的引用。触发命令执行,但不向接收者直接发送请求。 注意,调用者并不负责创建命令对象:它通常会通过构造函数从客户端处获得预先生成的命令。
Receiver,接收者,定义业务逻辑。几乎任何对象都可以作为接收者。绝大部分命令只处理如何将请求传递到接收者的细节,接收者自己会完成实际的工作。简化代码,这些类可以与具体命令类进行合并。
Client,客户端,创建并配置具体命令对象。客户端必须将包括接收者实体在内的所有请求参数传递给命令的构造函数。此后,生成的命令就可以与一个或多个发送者相关联了。
命令模式类图表示如下:

伪代码实现
接下来将使用代码介绍下命令模式的实现。
// 1、命令基类,声明一个执行命令的接口
public interface ICommand {void execute();
}// 2、具体命令类,实现各种类型的请求
public class ConcreteCommandA implements ICommand {private Receiver receiver;public ConcreteCommandA(Receiver receiver) {this.receiver = receiver;}@Overridepublic void execute() {System.out.println("this is a concrete command A instance");receiver.actionA();}
}
public class ConcreteCommandB implements ICommand {private Receiver receiver;public ConcreteCommandB(Receiver receiver) {this.receiver = receiver;}@Overridepublic void execute() {System.out.println("this is a concrete command B instance");receiver.actionB();}
}// 3、接收者,定义业务逻辑。绝大部分命令只处理如何将请求传递到接收者的细节,接收者自己会完成实际的工作。为简化代码,这些类可以与具体命令类进行合并
public class Receiver {public void actionA() {System.out.println("action A in a receiver instance");}public void actionB() {System.out.println("action B in a receiver instance");}
}// 4、调用者,负责对请求进行初始化和触发命令执行。注意,调用者并不负责创建命令对象:它通常会通过构造函数从客户端处获得预先生成的命令
public class Invoker {private ICommand command;public Invoker(ICommand command) {this.command = command;}public void executeCommand() {this.command.execute();}
}// 5、客户端
public class CommandClient {public void test() {// (1) 创建接收者实例Receiver receiver = new Receiver();// (2) 创建命令实例ICommand commandA = new ConcreteCommandA(receiver);// (3) 创建调用者实例Invoker invokerA = new Invoker(commandA);// (4) 执行命令invokerA.executeCommand();ICommand commandB = new ConcreteCommandB(receiver);Invoker invokerB = new Invoker(commandB);invokerB.executeCommand();}
}
适用场景
在以下情况下可以考虑使用命令模式:
(1) 如果需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互,可考虑使用该模式。
(2) 如果需要通过操作来参数化对象,可考虑使用该模式。命令模式可将特定的方法调用转化为独立对象。这一改变也带来了许多有趣的应用:开发者可以将命令作为方法的参数进行传递、将命令保存在其他对象中,或者在运行时切换已连接的命令等。
(3) 如果需要将操作放入队列中、操作的执行或者远程执行操作,可考虑使该模式。同其他对象一样, 命令也可以实现序列化 (序列化的意思是转化为字符串),从而能方便地写入文件或数据库中。一段时间后,该字符串可被恢复成为最初的命令对象。因此,可以延迟或计划命令的执行。 但其功能远不止如此。使用同样的方式,还可以将命令放入队列、 记录命令或者通过网络发送命令。
(4) 如果需要实现命令的撤销(Undo)操作和恢复(Redo)操作,可考虑使该模式。为了能够回滚操作, 需要实现已执行操作的历史记录功能。 命令历史记录是一种包含所有已执行命令对象及其相关程序状态备份的栈结构。
这种方法有两个缺点。 首先, 程序状态的保存功能并不容易实现, 因为部分状态可能是私有的。 可以使用备忘录模式来在一定程度上解决这个问题。
其次, 备份状态可能会占用大量内存。 因此, 有时需要借助另一种实现方式:命令无需恢复原始状态,而是执行反向操作。反向操作也有代价: 它可能会很难甚至是无法实现。
优缺点
命令模式有以下优点:
(1) 可以实现撤销和恢复功能。
(2) 可以实现操作的延迟执行。
(3) 可以将一组简单命令组合成一个复杂命令。
(4) 符合开闭原则。可以解耦触发和执行操作的类。
(5) 符合单一职责原则。发起操作和执行操作的类进行解耦。
但是该模式也存在以下缺点:
(1) 代码可能会变得更加复杂。使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。
参考
《设计模式 可复用面向对象软件的基础》 Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides 著, 李英军, 马晓星等译
https://design-patterns.readthedocs.io/zh_CN/latest/behavioral_patterns/command.html 命令模式
https://refactoringguru.cn/design-patterns/command 命令模式
https://www.runoob.com/design-pattern/command-pattern.html 命令模式
https://www.cnblogs.com/adamjwh/p/10923122.html 简说设计模式——命令模式
相关文章:
命令模式(Command)
命令模式是一种行为设计模式,可将一个请求封装为一个对象,用不同的请求将方法参数化,从而实现延迟请求执行或将其放入队列中或记录请求日志,以及支持可撤销操作。其别名为动作(Action)模式或事务(Transaction)模式。 Command is …...
Dapper 微型orm的光
介绍 Dapper是一个轻量级的ORM(对象关系映射)框架,它可以方便地将数据库查询结果映射到.NET对象上,同时也支持执行原生SQL查询。下面我将详细介绍Dapper的使用方法。 安装Dapper 首先,你需要通过NuGet包管理器将Dap…...
Mysql随心记--第一篇
MylSAM:查询速度快,有较好的索引优化和数据压缩技术,但是它不支持事务 InnoDB:它支持事务,并且提供行级的锁定,应用也相当广泛 docker ps -a --filter "ancestormysql" 查看linux中创建了多少个d…...
使用dockerfile安装各种服务组件
使用dockerfile安装各种服务组件 elasticsearch、minio、mongodb、nacos、redis 一、使用dockerfile安装elasticsearch:7.8.0 1、Dockerfile文件 FROM elasticsearch:7.8.0 #添加分词器 ADD elasticsearch-analysis-ik /usr/share/elasticsearch/plugins/elasticsearch-anal…...
如何简单的无人直播
环境搭建 ffmpeg安装,我这里用的是centos搭建的,其他平台可以自己百度 yum -y install wgetwget --no-check-certificate https://www.johnvansickle.com/ffmpeg/old-releases/ffmpeg-4.0.3-64bit-static.tar.xztar -xJf ffmpeg-4.0.3-64bit-static.ta…...
【基于HBase和ElasticSearch构建大数据实时检索项目】
基于HBase和ElasticSearch构建大数据实时检索项目 一、项目说明二、环境搭建三、编写程序四、测试流程 一、项目说明 利用HBase存储海量数据,解决海量数据存储和实时更新查询的问题;利用ElasticSearch作为HBase索引,加快大数据集中实时查询数…...
ProComponent 用法学习
相信很多同学都用过 Ant Design 这一 react 著名组件库,而 ProComponents 则是在 antd 之上进行封装的页面级组件库(指一个组件就可以搞定一个页面)。它同时也是 Ant Design Pro 中后台框架所用的主要组件库。如果你手上有要用 react 开发的中…...
巨人互动|Google海外户Google Analytics的优缺点是什么?
Google Analytics是一个由谷歌开发的网站分析工具,旨在帮助网站和移动应用程序运营者收集和分析数据,以更好地了解用户行为和改进业务。虽然Google Analytics具有许多优势,但也存在一些缺点。在本文中,我们将探讨Google Analytics…...
MySQL数据库的操作
MySQL 连接服务器 库的操作创建数据库数据库删除查看数据库进入数据库查看所在的数据库修改数据库显示创建语句查看连接情况 表的操作创建表查看数据库所有的表查看表的详细信息查看创建表时的详细信息删除表修改表名向表中插入数据在表结构中新增一列对表结构数据的修改删除表…...
人工智能行业岗位一览
人工智能行业的岗位薪资高、待遇好、涨薪快已经是公开的事实,那么在人工智能行业中具体有哪些职业岗位呢?对于普通人来说,想要入行人工智能又有哪些机会呢? 下面是人工智能领域中的一部分职业岗位,随着技术的不断发展&…...
《Linux运维实战:Docker基础总结》
一、简介 1、docker的基本结构是什么,包含哪些组件? docker的基本机构是c/s模式,即客户端/服务端模式。 由docker客户端和docker守护进程组成。docker客户端通过命令行或其它工具使用docker sdk与docker守护进程通信,发送容器管理…...
Clash 意外退出后 chrome / google 谷歌 浏览器无法连接互联网
解决方案: 以管理员模式打开命令行,输入:netsh winsock reset ,然后重启电脑 如果还不行的话, 在 chromevs中选中 设置>隐私和安全>安全>使用安全 dns> 使用您当前的服务提供商 即可...
89 | Python人工智能篇 —— 深度学习算法 Keras 实现 MNIST分类
本教程将带您深入探索Keras,一个开源的深度学习框架,用于构建人工神经网络模型。我们将一步步引导您掌握Keras的核心概念和基本用法,学习如何构建和训练深度学习模型,以及如何将其应用于实际问题中。 文章目录 Keras 构建实际mnist图像分类案例.1. 介绍2. 环境搭建3. 数据准…...
每天一道leetcode:剑指 Offer 32 - III. 从上到下打印二叉树 III(中等广度优先遍历)
今日份题目: 请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。 示例 给定二叉树: [3,9,20,null,null,15,7…...
day10 快速排序 方法重载 和 方法递推
方法重载 斐波拉契数列问题 使用重载思想解决 public static int method(int n){if (n 2 ){return 1 ;}return (n-1)*2method(n-1);}public static int f(int n){if (n 1){return 1;}if (n 2){return 2;}return f(n-1)f(n-2);} 快速排序 思维很简单,类似二…...
Qt 6. 其他类调用Ui中的控件
1. 把主类指针this传给其他类,tcpClientSocket new TcpClient(this); //ex2.cpp #include "ex2.h" #include "ui_ex2.h"Ex2::Ex2(QWidget *parent): QDialog(parent), ui(new Ui::Ex2) {ui->setupUi(this);tcpClientSocket new TcpClient…...
PHP 的不同版本(src 版、nts 版和 win 版)之间的区别和共同点。
在下载php时会有很多版本供我们选择,PHP 的不同版本(src 版、nts 版和 win 版)之间的区别又是什么呢。 src 版本:src 版本指的是 PHP 的源代码版本,您需要自行编译并安装它。这个版本通常用于自定义编译、开发环境和高…...
3 vue的if语法
vue的if语法是相当于一个标签的属性来写进去的,比如说<h1 v-if“”>。要注意的是if语句里可以自动从数据层取值的,比如<h1 v-if"message">,这里就会自动把key为message的值取过来,而如果要传一个字符串&…...
python基础3——流程控制
文章目录 一、操作符1.1 比较操作符1.2 逻辑操作符1.3 成员操作符1.4 身份操作符 二、流程控制2.1 条件判断2.2 循环语句2.2.1 for循环2.2.2 while循环 2.3 continue与break语句2.4 文件操作函数 三、函数3.1 定义函数3.2 作用域3.3 闭包3.4 函数装饰器3.5 内建函数 一、操作符…...
kubernetes中最小组件——Pod
目录 一、Pod简介 二、Pod的使用方式 三、Pause——Pod中底层基础容器 四、为什么kubernetes这样设计Pod 五、Pod的分类 1.自主式Pod 2.控制器管理的Pod 3.静态Pod 六、Pod容器的分类 1. 基础容器(infrastructure container) 2. 初始化容器&am…...
【AI】AI安全工具:常用AI安全检测工具的使用教程
AI安全工具:常用AI安全检测工具的使用教程📝 本章学习目标:本章介绍实用工具,帮助读者掌握AI安全合规治理的工具使用。通过本章学习,你将全面掌握"AI安全工具:常用AI安全检测工具的使用教程"这一…...
小鹅通重磅升级|AI Agent 能力全面护航,私域智能经营新范式
*文中配图及虚拟数据仅作效果展示 随着人工智能越来越贴近经营场景,小鹅通紧扣各位商家的实际需求,在原有产品基础上,以AI Agent为核心,完成了新一轮产品升级——在原有功能基础上,引入场景skills,并通过sk…...
别墅装修避坑指南:8个容易被忽视但至关重要的技术要点
别墅装修项目复杂,其风险与普通家装不在一个量级。梳理这8个要点,能帮你建立清晰的工程思维,避免在信息不对称中踩坑。1️⃣ 报价单的“参数化”解析别只看总价,要看清单的颗粒度。一份规范的报价应像一份技术参数表,包…...
WebGLStudio.js虚拟文件系统完全指南:如何高效管理3D资源
WebGLStudio.js虚拟文件系统完全指南:如何高效管理3D资源 【免费下载链接】webglstudio.js A full open source 3D graphics editor in the browser, with scene editor, coding pad, graph editor, virtual file system, and many features more. 项目地址: http…...
从混乱到有序:ERP系统革新如何优化企业资源配置
ERP系统革新,助力企业资源配置达到最优状态在当今竞争激烈的商业环境中,企业要想脱颖而出,实现可持续发展,高效的资源配置是关键。而ERP(企业资源计划)系统的革新,正成为众多企业提升资源配置效…...
Pumba在Kubernetes中的实战部署:DaemonSet配置指南
Pumba在Kubernetes中的实战部署:DaemonSet配置指南 【免费下载链接】pumba Chaos testing, network emulation, and stress testing tool for containers 项目地址: https://gitcode.com/gh_mirrors/pu/pumba Pumba是一款强大的容器混沌测试工具,…...
快马AI助力:十分钟用开yun技术栈搭建微服务电商原型
最近尝试用开yun技术栈快速搭建微服务电商原型,发现结合InsCode(快马)平台的AI辅助功能,整个过程比想象中顺畅很多。记录下这个十分钟搭建原型的实践过程,特别适合需要快速验证想法的场景。 技术选型思路 开yun技术栈作为云原生领域的热门选…...
3dsconv终极指南:一键将3DS游戏转换为CIA格式的完整教程
3dsconv终极指南:一键将3DS游戏转换为CIA格式的完整教程 【免费下载链接】3dsconv Python script to convert Nintendo 3DS CCI (".cci", ".3ds") files to the CIA format 项目地址: https://gitcode.com/gh_mirrors/3d/3dsconv 你是否…...
Seed-Coder-8B-Base功能体验:支持多种主流编程语言补全
Seed-Coder-8B-Base功能体验:支持多种主流编程语言补全 你有没有过这样的时刻——写代码时,思路清晰,但手指却卡在重复的语法结构上?或者,面对一个熟悉的编程模式,却要手动敲出几十行几乎相同的代码&#…...
HoYo-Glyphs:11款米哈游游戏文字字体,轻松打造你的专属游戏世界
HoYo-Glyphs:11款米哈游游戏文字字体,轻松打造你的专属游戏世界 【免费下载链接】HoYo-Glyphs Constructed scripts by HoYoverse 米哈游的架空文字 项目地址: https://gitcode.com/gh_mirrors/ho/HoYo-Glyphs 你是否曾被《原神》中蒙德教堂的哥特…...
