命令模式简介
概念:
命令模式是一种行为设计模式,它将请求封装成一个对象,从而允许您将不同的请求参数化、队列化,并且能够在不同的时间点执行。通过引入命令对象(Command)来解耦发送者(Invoker)和接收者(Receiver),使得发送者无需知道具体的接收者或操作细节。命令对象封装了一系列操作,并提供了一个统一的方法(如execute()),以便调用这些操作。
特点:
- 解耦性:命令模式将发送者与接收者之间解耦,使得它们可以独立演化。
- 可扩展性:可以方便地添加新的命令类和接收类,而无需修改现有代码。
- 可撤销/重做:由于每个命令都包含了执行和撤销操作,因此可以轻松地实现撤销、重做等功能。
- 容易组合:多个简单命令可以组合成复杂命令,在需要时进行灵活组合。
优点:
- 降低系统的耦合度。发送者与接收者之间不存在直接关联关系。
- 更好地支持撤销、重做等功能。每个具体命令断言了相关操作及其撤销操作。
- 更好地支持日志和事务。可以记录命令的执行过程,以及在需要时进行回滚。
缺点:
- 可能会导致类爆炸。每个具体命令都需要一个对应的接收者类。
- 命令模式增加了系统的复杂性,因为它引入了额外的抽象层次。
适用场景:
- 需要将请求参数化、队列滑,并希望能够在不同时间执行。
- 需要支持撤销、重做等功能。
- 需要实现日志记录、事务管理等功能。
实现方式:
- 定义一个抽象命令(Command)接口或抽象类,其中包含一个execute()方法用于执行命令。
- 创建具体命令类,实现抽象命令接口或继承抽象命令类,并在其中编写具体操作逻辑及其撤销逻辑。
- 定义接收者(Receiver)类,该类包含真正执行操作的方法。
- 创建调用者(Invoker)对象,在其中维护一系列命令对象,并通过调用execute()方法来触发相应的操作。
实现代码
import java.util.ArrayList;
import java.util.List;// 抽象命令接口
interface Command {void execute();
}// 具体命令类1
class ConcreteCommand1 implements Command {private Receiver receiver;public ConcreteCommand1(Receiver receiver) {this.receiver = receiver;}@Overridepublic void execute() {receiver.action1();}
}// 具体命令类2
class ConcreteCommand2 implements Command {private Receiver receiver;public ConcreteCommand2(Receiver receiver) {this.receiver = receiver;}@Overridepublic void execute() {receiver.action2();}
}// 接收者类
class Receiver {public void action1() {System.out.println("执行操作1");}public void action2() {System.out.println("执行操作2");}
}// 调用者类/发送者类/Invoker类
class Invoker {private List<Command> commands = new ArrayList<>();// 添加命令到队列中public void addCommand(Command command) {commands.add(command);}// 执行所有的命令public void executeCommands() {for (Command command : commands) {command.execute();}commands.clear(); // 清空已执行的命令列表,可选操作。}
}public class Main {public static void main(String[] args) {// 创建接收者对象Receiver receiver = new Receiver();// 创建具体命令对象并指定接收者Command command1 = new ConcreteCommand1(receiver);Command command2 = new ConcreteCommand2(receiver);// 创建调用者对象,并添加命令到队列中Invoker invoker = new Invoker();invoker.addCommand(command1);invoker.addCommand(command2);// 执行所有命令invoker.executeCommands();}}
在上述代码中,我们定义了一个抽象的Command接口,其中包含了一个execute()方法。然后创建了两个具体的命令类:ConcreteCommand1和`ConcreteCommand2,它们实现了Command接口并重写了execute()`方法。这些具体的命令类将调用接收者类中的不同操作。
在接收者类中,我们定义了两个操作:action1()和action2()。
最后,我们创建了一个调用者类/发送者类/Invoker类。它维护一个命令队列,并提供添加命令和执行所有命令的方法。当调用执行所有命令的方法时,它会依次执行每个命令。
通过使用命令模式,可以将请求发送方与接收方解耦,并且可以轻松地添加新的具体命令而无需修改现有代码。此外,由于每个具体的命令都是独立封装的对象,因此可以轻松地进行参数化配置和传递。
相关文章:
命令模式简介
概念: 命令模式是一种行为设计模式,它将请求封装成一个对象,从而允许您将不同的请求参数化、队列化,并且能够在不同的时间点执行。通过引入命令对象(Command)来解耦发送者(Invoker)…...
Boost序列化指针
Boost.Serialization 还能序列化指针和引用。 由于指针存储对象的地址,序列化对象的地址没有什么意义,而是在序列化指针和引用时,对象的引用被自动地序列化。 代码 #include <boost/archive/text_oarchive.hpp> #include <boost/…...
NIO简单介绍
一、什么是NIO 1、Java NIO全称java non-blocking IO, 是指JDK提供的新API。从JDK1.4开始,Java提供了一系列改进的输入/输出的新特性,被统称为NIO(即New IO),是同步非阻塞的 2、NIO有三大核心部分: Channel(通道), Buf…...
linux进程杀不死
项目场景: 虚拟机 问题描述 linux进程杀不死 无反应 原因分析: 进程僵死zombie 解决方案: 进proc或者find命令找到进程所在地址 cat status查看进程杀死子进程...
5分钟带你搞懂RPA到底是什么?RPA能做什么?
一、RPA的定义 RPA,全称Robotic Process Automation,即机器人流程自动化,是一种软件解决方案,能够模拟人类在计算机上执行的操作,以实现重复性、繁琐任务的自动化。它与传统的计算机自动化有所不同,因为它…...
毫米波雷达 TI IWR1443 在 ROS 中进行 octomap 建图
个人实验记录 /mmwave_ti_ros/ros_driver/src/ti_mmwave_rospkg/launch/1443_multi_3d_0.launch <launch><!-- Input arguments --><arg name"device" value"1443" doc"TI mmWave sensor device type [1443, 1642]"/><arg…...
113双周赛
题目列表 2855. 使数组成为递增数组的最少右移次数 2856. 删除数对后的最小数组长度 2857. 统计距离为 k 的点对 2858. 可以到达每一个节点的最少边反转次数 一、使数组成为递增数组的最少右移次数 这题可以直接暴力求解,枚举出每种右移后的数组,将…...
React 全栈体系(九)
第五章 React 路由 一、相关理解 1. SPA 的理解 单页 Web 应用(single page web application,SPA)。整个应用只有一个完整的页面。点击页面中的链接不会刷新页面,只会做页面的局部更新。数据都需要通过 ajax 请求获取, 并在前端…...
阈值化分割,对灰度级图像进行二值化处理(数字图像处理大题复习 P8)
文章目录 画出表格求出灰度直方图 & 山谷画出结果图 画出表格 有几个0就写几,有几个1就写几,如图 求出灰度直方图 & 山谷 跟前面求灰度直方图的方法一样,找出谷底,发现结果为 4 画出结果图 最终的结果就是…...
vue3中withDefaults是什么
问: const props withDefaults(defineProps<{// 数据列表lotteryList: { pic: string; name?: string }[];// 中奖idwinId: number;// 抽奖初始转动速度initSpeed: number;// 抽奖最快转动速度fastSpeed: number;// 抽奖最慢转动速度slowSpeed: number;// 基本圈数baseCi…...
Android进阶之路 - 盈利、亏损金额格式化
在金融类型的app中,关于金额、数字都相对敏感和常见一些,在此仅记录我在金融行业期间学到的皮毛,如后续遇到新的场景也会加入该篇 该篇大多采用 Kotlin 扩展函数的方式进行记录,尽可能熟悉 Kotlin 基础知识 兄弟 Blog StringUti…...
工业蒸汽量预测(速通一)
工业蒸汽量预测(一) 赛题理解1、评估指标2、赛题模型3、解题思路 理论知识1、变量识别2、变量分析3、缺失值处理4、异常值处理5、变量转换6、新变量生成 数据探索1、导包2、读取数据3、查看数据4、可视化数据分布4.1箱型图4.2获取异常数据并画图4.3直方图…...
机器学习的主要内容
分类任务 回归任务 有一些算法只能解决回归问题有一些算法只能解决分类问题有一些算法的思路既能解决回归问题,又能解决分类问题 一些情况下, 回归任务可以转化为分类任务, 比如我们预测学生的成绩,然后根据学生的成绩划分为A类、…...
华为OD机试真题-分积木-2023年OD统一考试(B卷)
题目描述: Solo和koko是两兄弟,妈妈给了他们一大堆积木,每块积木上都有自己的重量。现在他们想要将这些积木分成两堆。哥哥Solo负责分配,弟弟koko要求两个人获得的积木总重量“相等”(根据Koko的逻辑),个数可以不同,不然就会哭,但koko只会先将两个数转成二进制再进行加…...
SpringBoot自动装配原理及分析
一、什么是自动装配 在使用SpringBoot的时候,会自动将Bean装配到IoC容器中。例如我们在使用Redis数据库的时候,会引入依赖spring-boot-starter-data-redis。在引入这个依赖后,服务初始化的时候,会将操作Redis需要的组件注入到IoC…...
Android开发笔记 :理解Fragment
Android开发笔记:理解Fragment 导言 本篇文章产生的原因很简单,就是我在了解Android Jetpack中的Lifecycle框架时发现Lifecycle具体时间和状态的更新都是由一个名为ReportFragment的Fragment来跟踪的,为了更好的了解Fragment是如何追踪Activ…...
std::chrono获取当前秒级/毫秒级/微秒级/纳秒级时间戳
当前时间戳获取方法 先使用std::chrono获取当前系统时间,然后将当前系统时间转换为纪元时间std::time_t类型,之后使用std::localtime对std::time_t类型转换为本地时间结构体std::tm类型,最后使用strftime对时间进行格式化输出。 其中std::t…...
sh文件介绍及linux下执行
Shell脚本是一种用于自动化任务和系统管理的脚本语言。它允许用户通过命令行界面执行一系列命令,从而简化了重复性任务的处理过程。 以下是关于Shell脚本的一些基本概念: 1. Shell脚本通常以“.sh”扩展名保存,例如“script.sh”。 2. Shell…...
js-cookie使用 js深度克隆(判断引用类型是数组还是对象的方法)
cookie和深度拷贝的使用 1、js-cookie使用2、js深度克隆 1、js-cookie使用 前端的本地存储分为 localstorage、sesstionstorage、cookie 但是咱们有时候需要做7天免登录的需求时,选择 cookie 作为前端的本地存储是在合适不过的了 直接操作 cookie 可以, …...
[Pytorch]语义分割任务分类的实现
文章目录 [Pytorch]语义分割任务分类的实现 [Pytorch]语义分割任务分类的实现 假如我们定义了一个网络用于语义分割任务,这个网络简称为model() 语义分割任务要做的是: 对于一个图片输入input,大小为(B,C,…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...
微服务通信安全:深入解析mTLS的原理与实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言:微服务时代的通信安全挑战 随着云原生和微服务架构的普及,服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...
大模型——基于Docker+DeepSeek+Dify :搭建企业级本地私有化知识库超详细教程
基于Docker+DeepSeek+Dify :搭建企业级本地私有化知识库超详细教程 下载安装Docker Docker官网:https://www.docker.com/ 自定义Docker安装路径 Docker默认安装在C盘,大小大概2.9G,做这行最忌讳的就是安装软件全装C盘,所以我调整了下安装路径。 新建安装目录:E:\MyS…...
GeoServer发布PostgreSQL图层后WFS查询无主键字段
在使用 GeoServer(版本 2.22.2) 发布 PostgreSQL(PostGIS)中的表为地图服务时,常常会遇到一个小问题: WFS 查询中,主键字段(如 id)莫名其妙地消失了! 即使你在…...
开疆智能Ethernet/IP转Modbus网关连接鸣志步进电机驱动器配置案例
在工业自动化控制系统中,常常会遇到不同品牌和通信协议的设备需要协同工作的情况。本案例中,客户现场采用了 罗克韦尔PLC,但需要控制的变频器仅支持 ModbusRTU 协议。为了实现PLC 对变频器的有效控制与监控,引入了开疆智能Etherne…...
