当前位置: 首页 > 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…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

Web中间件--tomcat学习

Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机&#xff0c;它可以执行Java字节码。Java虚拟机是Java平台的一部分&#xff0c;Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...

提升移动端网页调试效率:WebDebugX 与常见工具组合实践

在日常移动端开发中&#xff0c;网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时&#xff0c;开发者迫切需要一套高效、可靠且跨平台的调试方案。过去&#xff0c;我们或多或少使用过 Chrome DevTools、Remote Debug…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态

前言 在人工智能技术飞速发展的今天&#xff0c;深度学习与大模型技术已成为推动行业变革的核心驱动力&#xff0c;而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心&#xff0c;系统性地呈现了两部深度技术著作的精华&#xff1a;…...

6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础

第三周 Day 3 &#x1f3af; 今日目标 理解类&#xff08;class&#xff09;和对象&#xff08;object&#xff09;的关系学会定义类的属性、方法和构造函数&#xff08;init&#xff09;掌握对象的创建与使用初识封装、继承和多态的基本概念&#xff08;预告&#xff09; &a…...

区块链技术概述

区块链技术是一种去中心化、分布式账本技术&#xff0c;通过密码学、共识机制和智能合约等核心组件&#xff0c;实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点&#xff1a;数据存储在网络中的多个节点&#xff08;计算机&#xff09;&#xff0c;而非…...