当前位置: 首页 > news >正文

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.命令模式含义 命令模式&#xff0c;将一个请求封装为一个对象&#xff0c;从而使你可用不同的请求对客户进行参数化。对请求排队或记录请求日志&#xff0c;以及支持可撤销的操作。 命令模式乍一看&#xff0c;有点懵懵的。即使这个定义看完&#xff0c;也是不明…...

Linux编译宏BUILD_BUG_ON_ZERO

本系列文章主要写我在阅读Linux内核过程中&#xff0c;关注的比较难以理解但又设计巧妙的代码片段&#xff08;不关注OS的各个模块的设计思想&#xff0c;此部分我准备写在“深入理解Linux Kernel”系列文章中&#xff09;&#xff0c;一来通过内核代码复习一下C语言及汇编语言…...

从Arweave开始:4EVERLAND存储签入挑战开始

嗨&#xff0c;4evers&#xff0c; 今天&#xff0c;我们热烈欢迎您参加 Galxe 上的 4EVERLAND “Arweave 入门”活动。这是一项长期的重头活动&#xff0c;所有参与的用户都有机会获得相应的奖励。 Arweave 是一种革命性的去中心化存储协议&#xff0c;为寻求安全可靠的有价…...

数据结构—链表

链表 前言链表链表的概念及结构链表的分类 无头单向非循环链表的相关实现带头双向循环链表的相关实现顺序表和链表&#xff08;带头双向循环链表&#xff09;的区别 前言 顺序表是存在一些固有的缺陷的&#xff1a; 中间/头部的插入删除&#xff0c;时间复杂度为O(N)&#xf…...

windows 10/11 修改右键新建菜单

问题&#xff1a;修改右键新建菜单内容 解决方法&#xff1a;使用软件ShellNew Settings 1.打开软件 2.根据需要取消勾选项 3.最终效果...

6.修饰符

文章目录 6.1 在一个静态方法内调用一个非静态成员为什么是非法的?6.2 静态方法和实例方法有何不同 6.1 在一个静态方法内调用一个非静态成员为什么是非法的? 由于静态方法可以不通过对象进行调用&#xff0c;因此在静态方法里&#xff0c;不能调用其他非静态变量&#xff0…...

【leetcode难题】2569. 更新数组后处理求和查询【线段树实现01翻转和区间求和模版】

题目截图 题目分析 关键就是记录每次操作2时&#xff0c;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…...

练习时长两年半的入侵检测

计算机安全的三大中心目标是&#xff1a;保密性 (Conf idential ity) 、完整性 (Integrity) 、可用性 (Availability) 。 身份认证与识别、访问控制机制、加密技术、防火墙技术等技术共同特征就是集中在系统的自身加固和防护上&#xff0c;属于静态的安全防御技术&#xff0c;…...

【弹力设计篇】聊聊隔离设计

为什么需要隔离设计 隔离其实就是Bulkheads&#xff0c;隔板。在生活中隔板的应用主要在船舱中进行设计&#xff0c;目的是为了避免因一处漏水导致整个船都沉下去。可以将故障减少在一定的范围内&#xff0c;而不是整个船体。 从架构演变来说的话&#xff0c;大多数系统都是从…...

MFC 透明窗体

如何制作透明窗体 &#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f; 使用SetLayeredWindowAttributes可以方便的制作透明窗体&#xff0c;此函数在w2k以上才支持,而且如果希望直接使用的话&#xff0c;可能需要下载最新的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、单页应用 &#xff08;1&#xff09;单页应用是什么 单页面应用(SPA&#xff1a;Single Page Application): 所有功能在 一个html页面 上实现具体示例: 网易云音乐 https://music.163.com/ &#xff08;2&#xff09;单页面应用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 主要的挑战和未来发展分为三个部分&#xff0c;即 1、特征集成和计算成本降低、 2、数据增强和数据集收集、 3、学习方式和模态-对象分布 1、特征集成和计算成本降低 为了同时捕获局部和全局特征来提高模型性能&#xff0c;目前大多数工作只是…...

深度学习入门(二):神经网络整体架构

一、前向传播 作用于每一层的输入&#xff0c;通过逐层计算得到输出结果 二、反向传播 作用于网络输出&#xff0c;通过计算梯度由深到浅更新网络参数 三、整体架构 层次结构&#xff1a;逐层变换数据 神经元&#xff1a;数据量、矩阵大小&#xff08;代表输入特征的数量…...

rust 配置

rustup 镜像 在 cmd 中输入以下代码&#xff0c;设置环境变量 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 &#xff08;67&#xff09;-- 算法导论6.5 6题 六、在 HEAP-INCREASE-KEY 的第 5 行的交换操作中&#xff0c;一般需要通过三次赋值来完成。想一想如何利用INSERTION-SORT 内循环部分的思想&#xff0c;只用一次赋值就完成这一交换操作? 文…...

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上的图神经网络入门博客&#xff1a; A Gentle Introduction to Graph Neural Network…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制&#xff08;1&#xff09;三次握手①握手过程②对握手过程的理解 &#xff08;2&#xff09;四次挥手&#xff08;3&#xff09;握手和挥手的触发&#xff08;4&#xff09;状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...

BLEU评分:机器翻译质量评估的黄金标准

BLEU评分&#xff1a;机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域&#xff0c;衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标&#xff0c;自2002年由IBM的Kishore Papineni等人提出以来&#xff0c;…...

ThreadLocal 源码

ThreadLocal 源码 此类提供线程局部变量。这些变量不同于它们的普通对应物&#xff0c;因为每个访问一个线程局部变量的线程&#xff08;通过其 get 或 set 方法&#xff09;都有自己独立初始化的变量副本。ThreadLocal 实例通常是类中的私有静态字段&#xff0c;这些类希望将…...