Java设计模式-命令模式
命令模式
1.命令模式含义
命令模式,将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化。对请求排队或记录请求日志,以及支持可撤销的操作。
命令模式乍一看,有点懵懵的。即使这个定义看完,也是不明所以。但是结合例子来讲的话,就比较容易理解了。
其实它就是把一个类能做的事情,使用具体的对象Command类来包装一下,当客户端想调用某个方法的时候,他需要通过具体的Command类来进行调用,而不能直接实例化那个类然后调用类方法。这样的话就将类的调用和调用请求的发出者给相互隔离开,解耦了。这样具体的请求执行者就不需要关注,到底是谁发出的这个请求执行命令,只需要把要执行的命令执行完即可。
比如现在路边有一个三轮车的烧烤摊,烧烤摊只有一个老板负责点单、收款、烤肉、分发烤好的肉这些事情。那么这个老板其实就是行为实现者,然后买烧烤的客人就是行为请求者。在这种情况下,作为行为实现者的老板,承担的事情职责就非常多,客户与老板紧耦合了,老板要处理的事情很多就非常容易出错,混乱。
而如果换一种方式,烧烤摊的老板赚到钱了,不再使用三轮车了,直接租了一个店面,招了一个服务员来帮忙。这下客人来吃烧烤的时候,就不用老板来负责点单、收款、分发烤肉的事情了,这些事情交给服务员来干,当客户需要烧烤的时候,只需要由服务员告诉老板需要几串羊肉串、几串五花肉即可,老板不需要知道这些烤串是哪个客户要的,他只需要把这些烤串烤完,交给服务员就行。这样老板和顾客就是松耦合了,老板只需要接收服务员的命令,即可有序、高效的完成烧烤订单。
这个行为请求者与行为实现者实现解耦的过程,其实就是命令模式了。它将客人的请求封装对象,由服务员统一接收,服务员接收完这些命令对象后,将命令对象转达给老板,老板统一执行这些命令,老板不需要关心谁发出的命令请求,直接执行完命令即可,这样就不会出现手忙脚乱的问题了。
2.代码示例
下面以烧烤为例展示一下命令模式的代码
2.1Receiver类
Receiver类是命令接受者对象,定义了命令接受者可以做的事情
public class Receiver {public void bakeMutton(){System.out.println("烤羊肉");}public void bakeBeef(){System.out.println("烤牛肉");}public void bakeBread(){System.out.println("烤面包");}public void bakeLobster(){System.out.println("烤小龙虾");}
}
2.2Command类
Command类是命令抽象类,定义了一个命令接受者对象,以及命令执行的抽象方法
public abstract class Command {protected Receiver receiver;public Command(Receiver receiver) {this.receiver = receiver;}public abstract void execute();
}
2.3BakeBeefCommand类
BakeBeefCommand烤牛肉类,是Command类的具体子类实现
public class BakeMuttonCommand extends Command{public BakeMuttonCommand(Receiver receiver) {super(receiver);}@Overridepublic void execute() {receiver.bakeMutton();}
}
2.4BakeBreadCommand类
BakeBreadCommand烤面包类,是Command类的具体子类实现
public class BakeBreadCommand extends Command{public BakeBreadCommand(Receiver receiver) {super(receiver);}@Overridepublic void execute() {receiver.bakeBread();}
}
2.5BakeLobsterCommand类
BakeLobsterCommand烤小龙虾类,是Command的具体子类实现
public class BakeLobsterCommand extends Command{public BakeLobsterCommand(Receiver receiver) {super(receiver);}@Overridepublic void execute() {receiver.bakeLobster();}
}
2.6BakeMuttonCommand类
BakeMuttonCommand烤羊肉串类,是Command的具体子类实现
public class BakeMuttonCommand extends Command{public BakeMuttonCommand(Receiver receiver) {super(receiver);}@Overridepublic void execute() {receiver.bakeMutton();}
}
2.7Invoker类
Invoker类是具体命令的接收者,用于接收客户的所有命令,然后将命令转达给执行者,执行这些命令
public class Invoker {private List<Command> command = new ArrayList<>();public void setCommand(Command command) {this.command.add(command);}public void executeCommand(){for (Command comm : command) {comm.execute();}}
}
2.8测试类
public class MainApp {public static void main(String[] args) {Receiver receiver = new Receiver();Command command = new BakeMuttonCommand(receiver);Command breadCommand = new BakeBreadCommand(receiver);Command lobsterCommand = new BakeLobsterCommand(receiver);Invoker invoker = new Invoker();invoker.setCommand(command);invoker.setCommand(breadCommand);invoker.setCommand(lobsterCommand);invoker.executeCommand();}
}
运行结果
烤羊肉
烤面包
烤小龙虾
3.命令模式优点
- 能够比较容易的设计一个命令队列
- 在需要的情况下,可以比较容易地将命令记入日志
- 允许接收请求的一方决定是否要解决请求
- 可以容易的实现对请求的撤销和重做
- 容易扩展新的命令类
- 能够把请求一个操作的对象,与知道怎么执行一个操作的对象分隔开
4.总结
命令模式能够实现将请求发出者和请求执行者进行解耦,便于实现请求的撤销、重做等操作。但是命令模式并不是一旦碰到类似情况的时候就要使用,而是要在确定需要使用的时候再使用,不要在自己猜测的基础上给系统增加不必要的功能,不能为了用命令模式而用命令模式,这点要考虑清楚。
这篇命令模式,感觉写的有点模模糊糊的,大家可以多看两遍示例代码理解一下。
相关文章:
Java设计模式-命令模式
命令模式 1.命令模式含义 命令模式,将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化。对请求排队或记录请求日志,以及支持可撤销的操作。 命令模式乍一看,有点懵懵的。即使这个定义看完,也是不明…...
Linux编译宏BUILD_BUG_ON_ZERO
本系列文章主要写我在阅读Linux内核过程中,关注的比较难以理解但又设计巧妙的代码片段(不关注OS的各个模块的设计思想,此部分我准备写在“深入理解Linux Kernel”系列文章中),一来通过内核代码复习一下C语言及汇编语言…...
从Arweave开始:4EVERLAND存储签入挑战开始
嗨,4evers, 今天,我们热烈欢迎您参加 Galxe 上的 4EVERLAND “Arweave 入门”活动。这是一项长期的重头活动,所有参与的用户都有机会获得相应的奖励。 Arweave 是一种革命性的去中心化存储协议,为寻求安全可靠的有价…...
数据结构—链表
链表 前言链表链表的概念及结构链表的分类 无头单向非循环链表的相关实现带头双向循环链表的相关实现顺序表和链表(带头双向循环链表)的区别 前言 顺序表是存在一些固有的缺陷的: 中间/头部的插入删除,时间复杂度为O(N)…...
windows 10/11 修改右键新建菜单
问题:修改右键新建菜单内容 解决方法:使用软件ShellNew Settings 1.打开软件 2.根据需要取消勾选项 3.最终效果...
6.修饰符
文章目录 6.1 在一个静态方法内调用一个非静态成员为什么是非法的?6.2 静态方法和实例方法有何不同 6.1 在一个静态方法内调用一个非静态成员为什么是非法的? 由于静态方法可以不通过对象进行调用,因此在静态方法里,不能调用其他非静态变量࿰…...
【leetcode难题】2569. 更新数组后处理求和查询【线段树实现01翻转和区间求和模版】
题目截图 题目分析 关键就是记录每次操作2时,nums1中的1的个数这就需要实现线段树进行区间反转以及区间求和 ac code class Solution:def handleQuery(self, nums1: List[int], nums2: List[int], queries: List[List[int]]) -> List[int]:n len(nums1)m le…...
练习时长两年半的入侵检测
计算机安全的三大中心目标是:保密性 (Conf idential ity) 、完整性 (Integrity) 、可用性 (Availability) 。 身份认证与识别、访问控制机制、加密技术、防火墙技术等技术共同特征就是集中在系统的自身加固和防护上,属于静态的安全防御技术,…...
【弹力设计篇】聊聊隔离设计
为什么需要隔离设计 隔离其实就是Bulkheads,隔板。在生活中隔板的应用主要在船舱中进行设计,目的是为了避免因一处漏水导致整个船都沉下去。可以将故障减少在一定的范围内,而不是整个船体。 从架构演变来说的话,大多数系统都是从…...
MFC 透明窗体
如何制作透明窗体 ????? 使用SetLayeredWindowAttributes可以方便的制作透明窗体,此函数在w2k以上才支持,而且如果希望直接使用的话,可能需要下载最新的SDK。不过此函数在w2k的user32.dll里有实…...
C++笔记之vector的resize()和clear()用法
C笔记之vector的resize()和clear()用法 code review! 文章目录 C笔记之vector的resize()和clear()用法1.resize()2.clear() 1.resize() 运行 2.clear() 运行...
Vue2基础九、路由
零、文章目录 Vue2基础九、路由 1、单页应用 (1)单页应用是什么 单页面应用(SPA:Single Page Application): 所有功能在 一个html页面 上实现具体示例: 网易云音乐 https://music.163.com/ (2)单页面应用VS多页面…...
移动零——力扣283
题目描述 双指针 class Solution{ public:void moveZeroes(vector<int>& nums){int n nums.size(), left0, right0;while(right<n){if(nums[right]){swap(nums[right], nums[left]);left;}right;}} };...
Transformer+MIA Future Work
TransformerMIA Future Work 主要的挑战和未来发展分为三个部分,即 1、特征集成和计算成本降低、 2、数据增强和数据集收集、 3、学习方式和模态-对象分布 1、特征集成和计算成本降低 为了同时捕获局部和全局特征来提高模型性能,目前大多数工作只是…...
深度学习入门(二):神经网络整体架构
一、前向传播 作用于每一层的输入,通过逐层计算得到输出结果 二、反向传播 作用于网络输出,通过计算梯度由深到浅更新网络参数 三、整体架构 层次结构:逐层变换数据 神经元:数据量、矩阵大小(代表输入特征的数量…...
rust 配置
rustup 镜像 在 cmd 中输入以下代码,设置环境变量 setx RUSTUP_UPDATE_ROOT https://mirrors.tuna.tsinghua.edu.cn/rustup/rustup setx RUSTUP_DIST_SERVER https://mirrors.tuna.tsinghua.edu.cn/rustupcrates.io 索引镜像 在 C:\Users\用户名\.cargo\config 文…...
文心一言 VS 讯飞星火 VS chatgpt (67)-- 算法导论6.5 6题
文心一言 VS 讯飞星火 VS chatgpt (67)-- 算法导论6.5 6题 六、在 HEAP-INCREASE-KEY 的第 5 行的交换操作中,一般需要通过三次赋值来完成。想一想如何利用INSERTION-SORT 内循环部分的思想,只用一次赋值就完成这一交换操作? 文…...
6、Kubernetes核心技术 - Pod
目录 一、概述 二、Pod机制 2.1、共享网络 2.2、共享存储 三、Pod资源清单 四、 Pod 的分类 五、Pod阶段 六、Pod 镜像拉取策略 ImagePullBackOff 七、Pod 资源限制 八、容器重启策略 一、概述 Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。P…...
VlanIf虚拟接口 通信技术(二十三课)
一 Vlan技术之间的通信 单臂路由(One-Arm Routing)是一种网络架构设计方式,通常用于部署网络设备(如防火墙、负载均衡器等)实现网络流量控制和安全策略。在单臂路由中,网络设备只有一个物理接口与局域网(LAN)或广域网(WAN)相连。 1.2 交换机 数据链路层 (第二层)…...
图神经网络(GNN)入门学习笔记(直观且简单)
文章目录 图的定义和表示可以使用图数据结构的问题将图结构用于机器学习的挑战最基本的图神经网络概述汇聚操作基于信息传递的改进图神经网络全局向量信息的利用 本篇文章参考发表于Distill上的图神经网络入门博客: A Gentle Introduction to Graph Neural Network…...
调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...
Python 高效图像帧提取与视频编码:实战指南
Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...
[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG
TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...
《Docker》架构
文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器,docker,镜像,k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...
当下AI智能硬件方案浅谈
背景: 现在大模型出来以后,打破了常规的机械式的对话,人机对话变得更聪明一点。 对话用到的技术主要是实时音视频,简称为RTC。下游硬件厂商一般都不会去自己开发音视频技术,开发自己的大模型。商用方案多见为字节、百…...
aurora与pcie的数据高速传输
设备:zynq7100; 开发环境:window; vivado版本:2021.1; 引言 之前在前面两章已经介绍了aurora读写DDR,xdma读写ddr实验。这次我们做一个大工程,pc通过pcie传输给fpga,fpga再通过aur…...
