命令模式-请求发送者与接收者解耦
去小餐馆吃饭的时候,顾客直接跟厨师说想要吃什么菜,然后厨师再开始炒菜。去大点的餐馆吃饭时,我们是跟服务员说想吃什么菜,然后服务员把这信息传到厨房,厨师根据这些订单信息炒菜。为什么大餐馆不省去这个步骤,像小餐管那样点菜呢?原因主要有以下几点:
- 提供效率。厨师专注炒菜就行,而不必花时间跟客户接触。
- 各司其职,提高服务质量。厨师擅长炒菜,而服务员擅长跟顾客打交道。
- 使工作有条不紊的进行。不会像小餐馆那样,来了个新客户,需要马上停止炒菜,去招呼客人,而另一边客户要在催着上菜。
- 阻断客户与厨师的接触。客户无须知道炒菜的厨师是谁,厨师也不需要知道他为谁炒的菜。
在这里,服务员发挥着“命令”的作用,将客户的命令传递给厨师,厨师做出相应。而这种模式是一种“命令模式”。
1 命令模式概述
引入一个命令类,通过命令类来降低发送者和接收者的耦合度。将一个请求封装成一个命令对象,发送者只需指定一个命令对象,再通过命令对象来调用请求接收者的处理方法。
图 命令模式结构图
Command:抽象命令类,一般是抽象类或接口。声明了用于执行请求的execute()等方法,通过这些方法可调用请求接收者相关操作。
ConcreteCommand:具体命令类,对应具体接收者对象,维护了一个接收者对象的引用,在实现execute()方法时,将调用接收者对象的相关操作(action()方法等)。
Invoker:调用者,即请求发送者。通过命令对象来执行请求。
Reciver:接收者,执行与请求相关的操作,具体实现对请求的业务处理。
public interface Command {String getName();void makeOrder(String name);}public class WaiterCommand implements Command{private final String name;private CookReceiver cookReceiver;public WaiterCommand(String name, CookReceiver cookReceiver) {this.name = name;this.cookReceiver = cookReceiver;}public void setCookReceiver(CookReceiver cookReceiver) {this.cookReceiver = cookReceiver;}@Overridepublic String getName() {return name;}@Overridepublic void makeOrder(String name) {System.out.print(" " + cookReceiver.getName() + ":");cookReceiver.cooking(name);}}
public class CookReceiver {private final String name;public CookReceiver(String name) {this.name = name;}public String getName() {return name;}public void cooking(String name) {System.out.println("开始做菜:" + name);}}
public class CustomerInvoker {private Command waiter;public CustomerInvoker(Command waiter) {this.waiter = waiter;}public void changeWaiter(Command waiter) {this.waiter = waiter;}public void makeOrder(String name) {System.out.print(waiter.getName() + "为客户下单");waiter.makeOrder(name);}}
public class Client {private final static List<Command> waiterList = new ArrayList<>();static {CookReceiver cook1 = new CookReceiver("黄师傅");CookReceiver cook2 = new CookReceiver("刘师傅");waiterList.add(new WaiterCommand("小李",cook1));waiterList.add(new WaiterCommand("小张",cook2));waiterList.add(new WaiterCommand("小王", cook1));}public static void main(String[] args) {String[] menu = {"辣椒炒肉","剁椒鱼头","清蒸豆腐","爆炒花甲","酸辣螺蛳粉"};Random random = new Random();for (int i = 0; i < 6; i++) {CustomerInvoker invoker = new CustomerInvoker(waiterList.get(random.nextInt( waiterList.size())));invoker.makeOrder(menu[random.nextInt(menu.length)]);System.out.println("--------------");}
// 运行结果:
// 小王为客户下单 黄师傅:开始做菜:酸辣螺蛳粉
// --------------
// 小王为客户下单 黄师傅:开始做菜:辣椒炒肉
// --------------
// 小张为客户下单 刘师傅:开始做菜:剁椒鱼头
// --------------
// 小张为客户下单 刘师傅:开始做菜:爆炒花甲
// --------------
// 小王为客户下单 黄师傅:开始做菜:辣椒炒肉
// --------------
// 小王为客户下单 黄师傅:开始做菜:酸辣螺蛳粉
// --------------}}
命令模式的本质是对请求进行封装,一个请求对应一个命令。将发送命令与执行命令分割开,但不能减少类的数量。
1.1 命令队列
一个请求发送者发送一个请求时,不止一个请求接收者产生响应,这些接收者将逐个执行业务方法,完成对请求的处理。
图 命令队列结构图
2 优缺点
优点:
- 降低系统的耦合度,请求者与接收者之间完全解耦,相同的请求者可对应不同的接收者。同样,相同的接收者也也可以供不同的请求者使用,两者具有良好的独立性。
- 新的命令可用很容易地加入系统中。增加新的具体命令不会影响其他类,符合开闭原则。
- 笔记容易设计一个命令队列或宏命令。
- 为请求的撤销和恢复操作提供了一种设计和实现方案。
缺点:
1)会导致系统有过多的具体命令类。
3 适用场景
- 需要将请求调用者和请求接收者解耦。
- 系统需要支持命令的撤销和恢复操作。
- 需要将一组操作组合在一起形成宏命令。
- 需要在不同的时间指定请求、将请求排队和执行请求。一个命令对象和请求的初始调用者可以有不同的生命期。即最初的请求发出者可能已经不在了,而命令对象本身仍然是活动的。可以通过该命令对象去调用请求接收者,而无须关系请求调用者的存在性,可以通过请求日志等机制来具体实现。
相关文章:

命令模式-请求发送者与接收者解耦
去小餐馆吃饭的时候,顾客直接跟厨师说想要吃什么菜,然后厨师再开始炒菜。去大点的餐馆吃饭时,我们是跟服务员说想吃什么菜,然后服务员把这信息传到厨房,厨师根据这些订单信息炒菜。为什么大餐馆不省去这个步骤…...

【雕爷学编程】Arduino动手做(186)---WeMos ESP32开发板
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的&#x…...
3、JSON数据的处理
3.1 介绍 JSON数据 Spark SQL can automatically infer the schema of a JSON dataset and load it as a DataFrame Spark SQL能够自动将JSON数据集以结构化的形式加载为一个DataFrame This conversion can be done using SparkSession.read.json on a JSON file 读取一个JSO…...

8月5日上课内容 nginx的优化和防盗链
全部都是面试题 nginx的优化和防盗链 重点就是优化: 每一个点都是面试题,非常重要,都是面试题 1、隐藏版本号(重点,一定要会) 备份 cp nginx.conf nginx.conf.bak.2023.0805 方法一:修改配…...
网络爬虫请求头中的Referer和User-Agent与代理IP的配合使用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8EJgMcgK-1691050515642)(https://cdn.nlark.com/yuque/0/2023/png/1313150/1691048724422-2a76d7b8-3ec3-48b7-9aec-d609d09b16d4.png#averageHue%2385b0a7&clientIdu3856fd20-7701-4&fromui&…...
RabbitMQ 生产者-消息丢失 之 场景分析
生产者-消息丢失 之 场景分析 生产者消息丢失的场景消息无法到达RabbitMQ连接断开信道关闭 RabbitMQ无法将消息入队交换机不存在无匹配队列 消息过期丢失消息丢失场景对比 生产者消息丢失的场景 生产者发送消息的流程如下:首先生产者和RabbitMQ服务器建立连接&…...

Hyper实现git bash在windows环境下多tab窗口显示
1.电脑上安装有git bash 下载链接:https://gitforwindows.org/ 安装Hyper 下载链接:官网 https://hyper.is/ 或者在百度云盘下载: https://pan.baidu.com/s/1BVjzlK0s4SgAbQgsiK1Eow 提取码:0r1f 设置 打开Hyper,依次点左上角-&g…...

Matlab的信号频谱分析——FFT变换
Matlab的信号频谱分析——FFT变换 Matlab的信号频谱分析 FFT是离散傅立叶变换的快速算法,可以将一个时域信号变换到频域。 有些信号在时域上是很难看出什么特征的。但是如果变换到频域之后,就很容易看出特征了。 这就是很多信号分析采用FFT变换的原因…...

如何从 Android 设备恢复已删除的文件?
从 Android 设备恢复已删除的文件很简单,但您需要了解内部恢复和SD 卡恢复之间的区别。 目前销售的大多数 Android 设备都配备了 SD 卡插槽(通常为 microSD),可以轻松添加额外的存储空间。该存储空间可用于存储照片、视频、文档&a…...

servlet生命周期和初始化参数传递
servlet生命周期和初始化参数传递 1、servlet生命周期 只有第一次访问才会初始化,之后访问都只执行service中的。 除非tomcat关闭重新启动: 2、初始化参数传递...

dvwa靶场通关(十一)
第十一关:Reflected Cross Site Scripting (XSS) low 这一关没有任何防护,直接输入弹窗 <script>alert(xss)</script> 打开网页源代码, 从源代码中我们可以看到,前面是输出的第一部分Hello,我们输入的脚…...

【Spring】使用注解存储Bean对象
目录 一、配置扫描路径(使用注解的方式存对象的前提) 二、使用类注解存储Bean对象 1、使用五大类注解存储Bean对象 2、为什么要这么多的类注解? 2.1、五大类注解之间的关系 3、获取Bean对象时的默认命名规则 三、使用方法注解来存储…...

怎么维护好自己的电脑
你的电脑已经成为你工作、学习、娱乐的最佳工具之一,但是如果你不做好电脑维护工作,就可能面临着电脑变慢、蓝屏、崩溃等问题。在这篇文章中,我们将介绍10个电脑维护步骤,让你的电脑更加稳定! 为什么需要电脑维护&…...

vscode中无法使用git解决方案
1 首先查看git安装目录 where git 2 找到bash.exe 的路径 比如:C:/Users/Wangzd/AppData/Local/Programs/Git/bin/bash 3 找到vscode的配置项setting.json 4 添加 "terminal.integrated.shell.windowns": "C:/Users/Wangzd/AppData/Local/Pr…...
MybatisPlus-CRUD,不带条件构造器的常用方法
mapper层 Repository public interface UserMapper extends BaseMapper<User> BaseMapper中封装好了增删改查的方法 后面直接调用就好了 测试类 SpringBootTest public class CrudTest {Autowiredprivate UserMapper userMapper;//新增Testpublic void insert(){//没…...

软件测试面试【富途面经分享】
目录 一面面经(1h) 二面面经 一面面经(1h) 一、对白盒黑盒灰盒测试的理解 答: 1、黑盒测试就当整个程序是个黑盒子,我们看不到它里面做了什么事情,只能通过输入输出看是否能得到我们所需的来…...

antd 库的 Table 组件中删除一个或多个选中的列表
先解释一下原代码每个方法的含义 const TablePage: React.FC () > {/* selectedRowKeys 指定选中项的 key 数组,需要和 onChange 进行配合在此处,通过 rowSelection.selectedRowKeys 来控制选中项。*/const [selectedRowKeys, setSelectedRowKeys] …...

针对java程序员的了解细节操作系统与进程
一、💛 操作系统(浅浅概念):是用来搞管理软件的 1.对下,要管理各种硬件设备 2.对上,要给应用程序提供一个稳定的运行环境 二、💙 进程:正在运行的程序,假如程序没有运行就不叫程序,…...
判定是否互为字符重排、回文排列
题1:判定是否互为字符重排 给定两个由小写字母组成的字符串 s1 和 s2,请编写一个程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串。 输入: s1 "abc", s2 "bca" 输出: true 输入: s1 &quo…...
QT QTextCharFormat 说明和使用
QTextCharFormat:设置文本编辑框字体,字号,加粗,倾斜,下划线,颜色 QTextCharFormat 类的一些常用属性和方法: setFont(const QFont &font): 设置字体。 setFontFamily(const QString &a…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...

tauri项目,如何在rust端读取电脑环境变量
如果想在前端通过调用来获取环境变量的值,可以通过标准的依赖: std::env::var(name).ok() 想在前端通过调用来获取,可以写一个command函数: #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...

热烈祝贺埃文科技正式加入可信数据空间发展联盟
2025年4月29日,在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上,可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞,强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...