技术成神之路:设计模式(二十二)命令模式
相关文章:技术成神之路:二十三种设计模式(导航页)
介绍
命令模式(Command Pattern)是一种行为设计模式,允许将请求(命令)封装为对象,从而使您可以使用不同的请求、队列或记录请求日志,以及支持可撤销操作。
1. 定义
命令模式将一个请求封装为一个对象,从而能够参数化其他对象以便于请求的发起、排队或日志记录。
2. 主要作用
- 将请求调用者与请求接收者解耦。
- 支持请求的排队和日志记录。
- 支持可撤销操作。
3.解决的问题
命令模式主要解决的是请求的发送者和接收者之间的紧耦合。通过将请求封装为对象,命令模式能够灵活地设计和扩展请求的处理。
4.模式原理
包含角色:
- 命令接口(Command): 定义执行命令的接口。
- 具体命令类(ConcreteCommand): 实现命令接口,定义与接收者之间的绑定。
- 接收者(Receiver): 知道如何执行与某个请求相关的操作。
- 调用者(Invoker): 持有命令对象并在需要时调用它。
UML类图:
示例代码:
通过Command
接口和具体命令类实现了对请求的封装,RemoteControl
类可以通过调用不同的命令来触发不同的行为。
// 命令接口
interface Command {void execute();void undo();
}// 命令接收者
class Light {public void on() {System.out.println("Light is ON");}public void off() {System.out.println("Light is OFF");}
}// 具体命令类
class LightOnCommand implements Command {private Light light;public LightOnCommand(Light light) {this.light = light;}@Overridepublic void execute() {light.on();}@Overridepublic void undo() {light.off();}
}class LightOffCommand implements Command {private Light light;public LightOffCommand(Light light) {this.light = light;}@Overridepublic void execute() {light.off();}@Overridepublic void undo() {light.on();}
}// 命令调用者
class RemoteControl {private Command command;public void setCommand(Command command) {this.command = command;}public void pressButton() {command.execute();}public void pressUndo() {command.undo();}
}
调用
public class CommandPatternDemo {public static void main(String[] args) {Light light = new Light();Command lightOn = new LightOnCommand(light);Command lightOff = new LightOffCommand(light);RemoteControl remote = new RemoteControl();remote.setCommand(lightOn);remote.pressButton();remote.pressUndo();remote.setCommand(lightOff);remote.pressButton();remote.pressUndo();}
}
打印输出
Light is ON
Light is OFF
Light is OFF
Light is ON
命令模式可能理解起来稍微麻烦一些,毕竟角色比较多,将示例代码和上面UML类图结合起来看,会更容易理解。
看到这个模式,让我想起了之前做过的一个项目,需要上位机和下位机或蓝牙模块不停的进行通信,接收和发送实时数据,指令要根据具体协议进行传输,都是字节数组,指令是按帧进行传输的,一条指令本身包括长度,校验和,头字节,尾字节等关键信息,附加的信息还有发送间隔,指令类型如485 或 232等,为了统一管理这些指令,就统一提取了命令接口。
为了防止指令发送顺序,使用到了队列,不停地喂数据,发送线程不停地取数据,这里的数据就是一个一个的具体命令对象,将命令取出来后,根据其内部信息,再判断是向下位机发送还是蓝牙模块发送,突然发现命令模式好像专门因这个场景而诞生的,哈哈哈。
多说两句,管理和发送不同协议的指令还不算太难,难的是通过一个数据接收类,统一接收并区别不同的指令,然后在不同的地方处理才是最难的,少则有两个不同协议,多则三个或以上,它们发过来都是一段字节数据,有可能是完整的指令,有可能只是一段指令,你不知道它是哪个协议的,只能将数据放到一个很大的字节数组中,供后续拼接,然后再不停的校验,而且要做到毫秒级提取,慢一点存放字节容器就会爆满,每种协议都有自己单独的校验方式,奇校验、偶校验、累加和,异或… 光是听到都头大,最后将领导写的初版代码,优化、验证、重写了无数遍,才完全理解,最后将领导的代码删了,使用了我的版本(可以平替,支持更多校验方式,更容易理解的代码),哈哈哈哈,一个能吹nb的功能。
说的有点多了,但那段回忆,一下就上来了,不吐不快。
5.优缺点
优点:
- 降低了系统的耦合度。
- 增强了系统的灵活性和可扩展性。
- 可以很方便地添加新的命令。
缺点:
- 需要创建许多类,增加了系统的复杂性。
- 如果命令过多,可能会导致系统的可维护性降低。
6.应用场景
- 界面菜单系统。
- 实现Undo/Redo功能。
- 请求需要排队的场景。
7.总结
命令模式通过将请求封装为对象,提供了灵活的请求处理方式。它有助于实现请求的解耦、可撤销操作和请求日志。尽管它增加了类的数量,但在需要复杂请求处理的系统中,它的优势是显而易见的。
相关文章:

技术成神之路:设计模式(二十二)命令模式
相关文章:技术成神之路:二十三种设计模式(导航页) 介绍 命令模式(Command Pattern)是一种行为设计模式,允许将请求(命令)封装为对象,从而使您可以使用不同的请求、队列或记录请求日…...
facebook账号类型有哪些?
Facebook的主要账号类型 在Facebook上,用户可以基于不同的目的和需求创建不同类型的账号,主要包括以下几类: 1. 个人账号 这是最常见的Facebook账号类型,每个用户都可以创建一个个人账号,分享生活动态、与朋友互动、…...

Flutter鸿蒙next 中如何实现 WebView【跳、显、适、反】等一些基础问题
✅近期推荐:求职神器 https://bbs.csdn.net/topics/619384540 🔥欢迎大家订阅系列专栏:flutter_鸿蒙next 💬淼学派语录:只有不断的否认自己和肯定自己,才能走出弯曲不平的泥泞路,因为平坦的大路…...

机器视觉:9点标定的原理与实现
一、什么是标定 标定就是将机器视觉处理得到的像素坐标转换成实际项目中使用到的毫米坐标。简单说即使看看实际单位距离内有几个像素,如下图所示,10mm的距离内有222个像素,那像素坐标和实际的毫米坐标就有个比例关系了。 二、九点标定 9点标…...

《深度学习》 了解YOLO基本知识
目录 一、关于YOLO 1、什么是YOLO 2、经典的检测方法 1)one-stage单阶段检测 模型指标介绍: 2)two-stage多阶段检测 二、关于mAP指标 1、概念 2、IOU 3、关于召回率和准确率 4、示例 5、计算mAP 一、关于YOLO 1、什么是YOLO YOL…...
什么是Kubernetes?K8s基础与工作原理
什么是 Kubernetes(K8s)? Kubernetes,通常简称为 K8s,是一个用于自动化部署、扩展和管理容器化应用程序的开源容器编排平台。它由 Google 于 2014 年开源,后来交由 CNCF(Cloud Native Computin…...
HTML5新增属性
1、HTML5 1.1 新增布局标签 header:用于定义文档或者section的页眉;footer:用于定义页面或section的底部信息;nav:用于定位页面上的导航链接部分;article:用于定位文档或者页面中的独立部分&a…...
软件开发术语(E开头)---持续更新
e—business 电子商务EAI (enterprise application integration)企业应用程序集成(整合)EBCO (empty base class optimization) 空基类优化(机制)Edge and Vertex Connectivity 割边/割点 Edge Coloring 边染色 EDI (Dlectronic Data Interchange)电子数据交换effic…...

多机器人编队避障算法(1)
文章目录 前言一、基于感知的避障1.基于感知的Epuck2避障思路(理论)2.基于感知的Epuck2避障实现(现实)3.距离传感器结合红外传感器修复避障Bug4.问题5.代码逻辑图 二、基于人工势场力的避障1.基于人工势场的Epuck2避障思路(理论)2.基于人工势场力的Epuck2避障实现(现实) 三、两…...

【网站项目】SpringBoot401超市收银系统
🙊作者简介:拥有多年开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。🌹赠送计算机毕业设计600个选题excel文件,帮助大学选题。赠送开题报告模板ÿ…...
KD树详解:多维数据高效搜索的利器
摘要 在处理多维数据时,如何高效地进行搜索与查询成为一个关键问题。KD树(K-Dimensional Tree)作为一种高效的多维数据结构,广泛应用于计算机视觉、机器人导航、数据库检索等领域。本文将详细介绍KD树的基本概念、结构、构建算法…...
从裸机到70B大模型2:基础设施设置与脚本
从裸机到70B大模型2:基础设施设置与脚本 随着深度学习技术的不断发展,神经网络模型的规模逐渐扩大,从单个模型到大型70B模型,所需的计算资源和存储空间也在不断增加。为了训练这些大型模型,我们需要一套高效的基础设施…...

shodan4,挂黑网站查找,弱口令网站搜索
myip参数 shodan myip(查看自己的出口IP,哪个地址链接的公网)挂黑网站查找 我们今天看一看找一下,有些已经被黑的网站好吧,就是利用shodan查看一下哪些网站已经被黑了。 shodan search -limit 10 -fields ip_str,port http.title:hacked b…...
spring boot 整合Knife4j
项目依赖配置 在本项目中,我们使用了以下关键依赖,以支持 Spring Boot 和 API 文档生成。 1. Spring Boot 版本 为了构建一个可靠和高效的 Spring Boot 应用程序,我们使用以下父级依赖: <parent><groupId>org.springframework.boot</groupId><art…...

攻防世界的新手web题解
攻防世界引导模式 1、disabled_button 好,给了一个按钮,第一道题目就不会做 看的wp<input disabled class"btn btn-default" style"height:50px;width:200px;" type"submit" value"flag" name"auth&q…...

【国潮来袭】华为原生鸿蒙 HarmonyOS NEXT(5.0)正式发布:鸿蒙诞生以来最大升级,碰一碰、小艺圈选重磅上线
在昨日晚间的原生鸿蒙之夜暨华为全场景新品发布会上,华为原生鸿蒙 HarmonyOS NEXT(5.0)正式发布。 华为官方透露,截至目前,鸿蒙操作系统在中国市场份额占据 Top2 的领先地位,拥有超过 1.1 亿 的代码行和 6…...
pytest 单元框架里,前置条件
1.使用 setup 函数级的(setup_function、teardown_function)只对函数用例生效,而且不在类中使用类级的(setup_class、teardown_class)在类中使用,类执行之前运行一次,类执行之后运行一次 类中方…...

数字IC后端实现 | Innovus各个阶段常用命令汇总
应各位读者要求,小编最近按照Innovus流程顺序整理出数字IC后端项目中常用的命令汇总。限于篇幅,这次只更新到powerplan阶段。有了这份Innovus常用命令汇总,学习数字IC后端从此不再迷路!如果大家觉得这个专题还不错,想继…...

MySQL全文索引检索中文
MySQL全文索引检索中文 5.7.6版本不支持中文检索,需要手动修改配置 ft_min_word_len 1 ,因为默认配置 4 SHOW VARIABLES LIKE ft%; show VARIABLES like ngram_token_size;配置 修改 MySQL 配置文件 vim /etc/my.cnf在配置的 [mysqld] 下面添加**ft_…...

pikachu靶场-Cross-Site Scripting(XSS)
sqli-labs靶场安装以及刷题记录-dockerpikachu靶场-Cross-Site Scripting pikachu靶场的安装刷题记录反射型xss(get)反射型xss(post)存储型xssDOM型xssDOM型xss-xxss盲打xss之过滤xss之htmlspecialcharsxss之href输出xss之js输出 pikachu靶场的安装 刷题记录 反射型xss(get) …...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...

循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...