技术成神之路:设计模式(二十二)命令模式

在这里插入图片描述

介绍

命令模式(Command Pattern)是一种行为设计模式,允许将请求(命令)封装为对象,从而使您可以使用不同的请求、队列或记录请求日志,以及支持可撤销操作。

1. 定义


命令模式将一个请求封装为一个对象,从而能够参数化其他对象以便于请求的发起、排队或日志记录。

2. 主要作用


  • 将请求调用者与请求接收者解耦。
  • 支持请求的排队和日志记录。
  • 支持可撤销操作。

3.解决的问题


命令模式主要解决的是请求的发送者和接收者之间的紧耦合。通过将请求封装为对象,命令模式能够灵活地设计和扩展请求的处理。

4.模式原理


包含角色:

  1. 命令接口(Command): 定义执行命令的接口。
  2. 具体命令类(ConcreteCommand): 实现命令接口,定义与接收者之间的绑定。
  3. 接收者(Receiver): 知道如何执行与某个请求相关的操作。
  4. 调用者(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.总结


命令模式通过将请求封装为对象,提供了灵活的请求处理方式。它有助于实现请求的解耦、可撤销操作和请求日志。尽管它增加了类的数量,但在需要复杂请求处理的系统中,它的优势是显而易见的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/57364.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Elasticsearch查询类型

1. 前言 搜索是Elasticsearch最核心的功能之一,它能够在海量数据中精准、快速地召回我们期望的文档。Elasticsearch支持各种复杂的条件搜索,查询类型之多,往往让新手一头雾水。甚至同一个搜索需求,可以用不同的查询类型来实现&am…

【人工智能】探索自然语言处理中的语音识别技术:基于Recurrent Neural Networks (RNN) 和长短期记忆网络(LSTM)模型的深入剖析

语音识别作为自然语言处理中的一项核心任务,近年来取得了长足的进展,尤其是在深度学习技术的推动下。在语音识别任务中,Recurrent Neural Networks (RNN) 尤其是其变体——长短期记忆网络(LSTM),展现出了卓…

python之电影天堂爬取下载链接

电影天堂_电影下载_高清首发 示例仅供参考&#xff0c;如有违权请联系删除&#xff01; 比如我们想要获取“2024必看影片” 鼠标右键&#xff0c;查看源文件 找到这里 匹配正则表达式 obj1 re.compile(r"2024必看热片.*?<ul>(?P<ul>.*?)</ul>&q…

如何使用python seaborn进行复杂的数据可视化操作?

数据可视化是数据分析中至关重要的一部分,它能够帮助我们更直观地理解数据,发现潜在的模式和趋势。 Python作为一种强大的编程语言,拥有众多数据可视化库,其中Seaborn是一个基于Matplotlib的高级可视化库,特别适合用于统计数据的可视化。 本文将深入探讨如何使用Seaborn…

每天练打字8:今日状况——常用字后五百击键4.5第1遍进行中,赛文速度105.75

今日跟打&#xff1a;738字 总跟打&#xff1a;125701字 记录天数&#xff1a;2459天 &#xff08;实际没有这么多天&#xff0c;这个是注册账号的天数&#xff09; 平均每天&#xff1a;50字 本周目标完成进度&#xff1a; 练习常用单字后500&#xff0c;击键3.5&#xff0c;…

springboot048校园资料分享平台(论文+源码)_kaic

校园资料分享平台 摘要 随着信息互联网购物的飞速发展&#xff0c;国内放开了自媒体的政策&#xff0c;一般企业都开始开发属于自己内容分发平台的网站。本文介绍了校园资料分享平台的开发全过程。通过分析企业对于校园资料分享平台的需求&#xff0c;创建了一个计算机管理校园…

vue查缺补漏

之前学习过vue基础&#xff0c;在工作上使用的时候也没有什么问题。最近在看30分钟学会Vue之核心语法,发现有一些不常用的、但挺重要的都快忘掉了&#xff0c;在此补漏一下。 搭建演示环境 创建index.html 导入 vue.min.js文件 <!DOCTYPE html> <html lang"en&…

【WSL2】Ubuntu20.04从零开搭PX4MavrosGazebo环境并测试

参考&#xff1a; 仿真平台基础配置&#xff08;对应PX4 1.13版&#xff09; 语雀 不需要卸载原来的gazebo&#xff0c;语雀对gazebo的插件做了修改&#xff0c;才需要那些步骤 “我们对Gazebo的ROS插件做了修改&#xff0c;因此需要源码编译。” mkdir -p ~/catkin_ws/src …

ElasticSearch与MySQL如何进行数据同步?

ElasticSearch&#xff08;ES&#xff09;与MySQL进行数据同步的需求在实际开发中非常常见&#xff0c;尤其是在需要高效的全文搜索或者数据分析时&#xff0c;通常使用MySQL作为事务数据库&#xff0c;ES作为搜索和查询引擎。那么要实现MySQL与ElasticSearch的数据同步&#x…

88.合并两个有序数组

目录 题目解法原地插入的函数如何使用sort()如何删除其中含0的数&#xff1f; 题目 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中&#xff0c;使合…

【存储设备专栏 2.4 -- linux 下块设备格式化命令详细介绍】

> 请阅读【嵌入式及芯片开发学必备专栏】< 文章目录 mksf 命令格式化为 FAT32格式化为 ext4格式化为 NTFS举例&#xff1a;格式化为 exFATSummary mksf 命令 在 Linux 中&#xff0c;使用 mkfs&#xff08;Make File System&#xff09;命令可以格式化块设备&#xff08…

20240818 字节跳动 笔试

文章目录 1、编程题1.11.21.31.4岗位:BSP驱动开发工程师-OS 题型:4 道编程题 1、编程题 1.1 小红的三消游戏: 小红在玩一个三消游戏,游戏中 n 个球排成一排,每个球都有一个颜色。若有 3 个颜色相同的球连在一起,则消除这 3 个球,然后剩下的球会重新连在一起。在没有 …

mysql 表

在 MySQL 中&#xff0c;表是数据库存储数据的基本单位。以下是关于 MySQL 表的一些重要知识&#xff1a; 一、表的结构 字段&#xff08;列&#xff09;&#xff1a; 每个表由若干个字段组成&#xff0c;字段定义了表中存储的数据类型和属性。例如&#xff0c;可以有整数类型&…

uniapp学习(007-3 壁纸项目:系统高度等信息的操作)

零基础入门uniapp Vue3组合式API版本到咸虾米壁纸项目实战&#xff0c;开发打包微信小程序、抖音小程序、H5、安卓APP客户端等 总时长 23:40:00 共116P 此文章包含第79p-第p82的内容 文章目录 自定义头部通屏我们自定义一个头部导航小程序的bug代码设计 获取系统的一些高度信…

CSS 设置网页的背景图片

背景 最近正好在写一个个人博客网站“小石潭记”&#xff0c;需要一张有水&#xff0c;有鱼的图片。正好玩原神遇到了类似场景&#xff0c;于是截图保存&#xff0c;添加到网站里面。以下是效果图&#xff1a; css 写个class&#xff0c;加到整个网页的body上 .bodyBg {ba…

【数据结构与算法】队列——数据世界中的“有序使者”

大家好&#xff0c;我是小卡皮巴拉 文章目录 目录 引言 一.队列的基本概念 1.1 队列的定义 1.2 队列的特性 1.3 队列的基本操作 二.队列的实现方式 2.1 基于链表的队列 2.2 基于数组的队列 三.基于链表的队列实现 定义链表队列的结构 初始化 入队列——向队列中插…

Yocto构建i.MX处理器目标镜像

1. 初始化构建环境 首先&#xff0c;通过运行imx-setup-release.sh脚本来初始化Yocto构建环境。此脚本的标准语法如下&#xff1a; $ DISTRO<distro name> MACHINE<machine name> source imx-setup-release.sh -b <build dir>DISTRO<distro configurati…

10-15个工作站用Pr处理25个4K视频 性能要求

在4K非编环境里&#xff0c;10-15台工作站运行Adobe Premiere&#xff0c;工作站跑25个4K ProRes 422 视频流。要求存储至少提供5GB/s的&#xff0c;2GB/s的读&#xff0c;并且提供650TB的空间。只有达到这样的要求&#xff0c;才能保证文件快速访问&#xff0c;以及编辑时做到…

代码工艺:写代码的好习惯

1. 充分校验入参 有一句话叫 “All input is evil”&#xff0c;即一切的输入都可能是恶意的。 因此&#xff0c;经验丰富的工程师会对接口的入参进行严格的校验&#xff0c;从最基础的非空、长度校验&#xff0c;到复杂的业务逻辑校验都不应忽略。例如&#xff0c;在典型的电…

C++ [项目] 飞机大战

现在才发现C游戏的支持率这么高&#xff0c;那就发几篇吧 一、基本介绍 支持Dev-C5.11版本(务必调为英文输入法),基本操作看游戏里的介绍,怎么做的……懒得说,能看懂就看注释,没有的自己猜,如果你很固执……私我吧 二、代码部分 /* 2024.8.13*/ #include<iostream> #i…