设计模式行为模式-命令模式
文章目录
- 前言
- 定义
- 结构
- 工作原理
- 优点
- 适用场景
- 消息队列模式Demo实现
- 分写业务
- 总结
前言
定义
命令模式(Command Pattern)是一种行为型设计模式,用于将请求封装为对象,从而使你可以使用不同的请求、队列或者日志请求来参数化其他对象。这样可以实现请求的参数化操作、队列化和日志化,且能够支持撤销操作。
结构
命令模式由以下几个核心组件组成:
- 命令(Command): 定义了执行操作的接口。通常包含一个
execute()方法,该方法在调用时会触发接收者执行相关操作。 - 具体命令(Concrete Command):实现命令接口,并将真正的操作委托给接收者。
- 接收者(Receiver):负责执行实际的操作。具体命令将请求委托给接收者完成具体的业务逻辑。
- 调用者(Invoker):负责调用命令并触发执行操作的方法。
- 客户端(Client):创建具体命令,并将其与接收者进行绑定。

工作原理
- 客户端创建一个具体命令,并将其与接收者(执行操作的对象)进行绑定。
- 调用者接收到命令后,将其存储起来,可以将命令存储在队列中,以支持撤销和重做操作。
- 调用者根据需要调用命令的
execute()方法。该方法会将请求传递给接收者,由接收者执行实际的操作。 - 接收者执行命令所指定的操作,并完成相应的业务逻辑。
优点
- 解耦调用者和接收者:调用者无需了解命令的具体实现,只需调用命令对象的方法来触发执行。
- 支持撤销和重做:通过存储命令的历史记录,可以方便地进行撤销和重做操作。
- 支持事务:可以通过一系列的命令组合形成事务,保证一组操作的原子性。
适用场景
- 需要将请求和执行操作解耦的情况。
- 需要支持撤销、重做、事务等操作的场景。
- 需要将一组操作组织成具体的命令队列或日志操作。
消息队列模式Demo实现
好的,下面是一个简单的使用 Java 实现的消息队列框架示例:
import java.util.LinkedList;
import java.util.Queue;// 消息接口
interface IMessage {void execute();
}// 具体消息类
class ConcreteMessage implements IMessage {private String content;public ConcreteMessage(String content) {this.content = content;}public void execute() {System.out.println("处理消息:" + content);}
}// 消息队列类
class MessageQueue {private Queue<IMessage> queue;public MessageQueue() {queue = new LinkedList<>();}public void enqueue(IMessage message) {queue.offer(message);}public IMessage dequeue() {return queue.poll();}public boolean isEmpty() {return queue.isEmpty();}
}// 消费者类
class Consumer {private MessageQueue messageQueue;public Consumer(MessageQueue messageQueue) {this.messageQueue = messageQueue;}public void processMessages() {while (!messageQueue.isEmpty()) {IMessage message = messageQueue.dequeue();message.execute();}}
}// 生产者类
class Producer {private MessageQueue messageQueue;public Producer(MessageQueue messageQueue) {this.messageQueue = messageQueue;}public void sendMessage(String content) {IMessage message = new ConcreteMessage(content);messageQueue.enqueue(message);System.out.println("发送消息:" + content);}
}// 客户端代码
public class Client {public static void main(String[] args) {// 创建消息队列对象MessageQueue messageQueue = new MessageQueue();// 创建消费者对象并启动消费者线程Consumer consumer = new Consumer(messageQueue);Thread consumerThread = new Thread(consumer::processMessages);consumerThread.start();// 创建生产者对象并发送消息Producer producer = new Producer(messageQueue);producer.sendMessage("消息1");producer.sendMessage("消息2");producer.sendMessage("消息3");// 等待消费者线程处理完所有消息try {consumerThread.join();} catch (InterruptedException e) {e.printStackTrace();}}
}
在上述示例中,我们实现了一个简单的消息队列框架。IMessage 是消息接口,定义了 execute() 方法表示具体的消息处理逻辑。ConcreteMessage 是具体的消息类,实现了 IMessage 接口,并在 execute() 方法中执行具体的处理操作。
MessageQueue 是消息队列类,使用 Queue 数据结构来保存消息对象,并提供了入队、出队和判断队列是否为空的方法。
Consumer 是消费者类,通过循环从消息队列中取出消息,并调用消息对象的 execute() 方法进行处理。
Producer 是生产者类,负责向消息队列中发送消息。
在客户端代码的 main() 方法中,我们创建了一个消息队列对象,然后分别创建了消费者对象和生产者对象。生产者使用 sendMessage() 方法向消息队列发送消息,而消费者通过启动一个新线程来调用 processMessages() 方法处理消息。

分写业务
这个业务代码实现了一个简单的消息队列框架。下面对代码进行逐步解释:
-
首先,定义了一个消息接口
IMessage,其中包含了execute()方法用于执行具体的消息处理操作。 -
接着,实现了具体的消息类
ConcreteMessage,它实现了IMessage接口,并在execute()方法中执行具体的消息处理逻辑。在本例中,处理逻辑简单地打印出消息内容。 -
然后,定义了消息队列类
MessageQueue,使用Queue数据结构来保存消息对象。它提供了入队(enqueue())、出队(dequeue())和判断队列是否为空(isEmpty())的方法。 -
接下来,定义了消费者类
Consumer,它通过循环从消息队列中取出消息,并调用消息对象的execute()方法进行处理。 -
最后,定义了生产者类
Producer,它负责向消息队列中发送消息。通过调用sendMessage()方法,生产者创建一个具体的消息对象并将其加入到消息队列中,同时打印出发送的消息内容。
在客户端代码的 main() 方法中,完成以下步骤:
-
创建了一个消息队列对象
messageQueue。 -
创建了消费者对象
consumer,并启动一个新线程来执行消费者的消息处理逻辑。 -
创建了生产者对象
producer,通过调用sendMessage()方法发送了三条消息。 -
最后,通过调用
join()方法等待消费者线程处理完所有消息。
总结
这个示例展示了如何使用 Java 实现一个简单的消息队列框架。通过将消息封装为对象,我们可以方便地在生产者和消费者之间进行消息的传递和处理。使用消息队列框架可以实现解耦和异步处理的优势。生产者负责发送消息,消费者负责处理消息,它们通过共享的消息队列进行通信。通过多线程的方式,我们可以实现并发的消息处理,提高系统的吞吐量和响应性能。
相关文章:
设计模式行为模式-命令模式
文章目录 前言定义结构工作原理优点适用场景消息队列模式Demo实现分写业务总结 前言 定义 命令模式(Command Pattern)是一种行为型设计模式,用于将请求封装为对象,从而使你可以使用不同的请求、队列或者日志请求来参数化其他对象…...
Linux-安装redis6.2.1及主备复制模式(replication)
Linux-安装redis6.2.1 下载redis6.2.1资源上传至安装目录解压及编译解压修改名称编译 修改配置文件主节点从节点 启动及测试启动主节点从节点 测试 下载redis6.2.1资源 地址》https://redis.io/download/ 上传至安装目录 例:/data/replication/ 解压及编译 解…...
新手做TikTok适合哪些类目?
现在很多小伙伴争先恐后想要在TikTok入驻,开店开直播带货赚钱,但是又怕自己是小白,不好拿捏这个平台。TikTok平台,适合小白做吗?现在tiktok千亿级的流量还处于蓝海阶段,想入局要趁早。那么肯定又有小伙伴疑…...
Open3D(C++) 点云格网分块
目录 一、算法概述二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、算法概述 点云格网分块是点云二维格网化的一个具体应用案例,与Open3D (C++) 使用点云创建数字高程模型DEM类似,对每个格…...
基于springboot跟redis实现的排行榜功能(实战)
概述 前段时间,做了一个世界杯竞猜积分排行榜。对世界杯64场球赛胜负平进行猜测,猜对1分,错误0分,一人一场只能猜一次。 1.展示前一百名列表。 2.展示个人排名(如:张三,您当前的排名106579)。 一.redis so…...
Mongodb常见操作命令
一、登录相关以及启动 启动服务mongodb: cd /usr/local/mongodb/bin ./mongod -f /data/mongodb/mongodb1.conf./mongod -f /data/mongodb/mongodb2.conf./mongod -f /data/mongodb/mongodb3.conf 登录mongodb数据库(mongodb默认端口:27017࿰…...
springcloud-nacos简述
Spring Cloud alibaba: nacos服务注册中心,配置中心 服务注册中心 1.项目父工程添加springcloudalibaba依赖 <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><ve…...
【SpringSecurity】十二、集成JWT搭配Redis实现退出登录
文章目录 1、登出的实现思路2、集成Redis3、认证成功处理器4、退出成功处理器5、修改token校验过滤器6、调试 1、登出的实现思路 这是目前的token实现图: 因为JWT的无状态,服务端无法在使用过程中主动废止某个 token,或者更改 token 的权限…...
Docker进入容器出现bash: vi: command not found
🎈1 参考文档 docker基础容器中bash: vi: command not found问题解决 | 你邻座的怪同学-CSDN 🔍2 问题描述 在使用 Docker 容器时,有时候里边没有安装vim,敲vim命令时提示说:vim: command not found。 这个时候就需要…...
Linux_6_文件查找与打包压缩
目录 文件查找与打包压缩1文件查找1.1 locate1.2 find1.2.1 指定搜索目录层级1.2.2对每个目录先处理目录内的文件,再处理目录本身1.2.3根据文件名和inode查找1.2.4 根据属主、属组查找1.2.5根据文件类型查找1.2.6空文件或目录1.2.7组合条件1.2.8 排除日录1.2.9根据文…...
JavaWeb_LeadNews_Day9-Redis实现用户行为
JavaWeb_LeadNews_Day9-Redis实现用户行为 网关配置点赞阅读不喜欢关注收藏文章详情-行为数据回显来源Gitee 网关配置 nacos: leadnews-app-gateway # 用户行为微服务 - id: leadnews-behavioruri: lb://leadnews-behaviorpredicates:- Path/behavior/**filters:- StripPrefi…...
IntelliJ IDEA2021.3.1 使用 MybatisCodeHelperPro插件
一、 下载 下载破解后的 MybatisCodeHelperPro 的 V3.2.2版本 V3.2.2-CSDN 或者 V3.2.2-Gitee 二、 应用 将下载下来的Zip文件 放到电脑上的某个位置 (最好放在Idea 管理插件的 plugins 下) 然后自从搜索 Idea如何从磁盘中应用插件 三、激活 由于已经破解过了 但是还是需要激活…...
el-date-picker 等 点击无反应不回显问题解决
如上图,编辑回显正常,但是时间控件在拖动过程中时间不会跟随改变。 解决办法: <el-date-picker input"onInput()" ...><el-input input"onInput()" ...>js中onInput() {this.$forceUpdate();},...
Ansible学习笔记12
playbook: playbook(剧本):是ansible用于配置、部署和管理被控节点的剧本,用于Ansible操作的编排。 使用的是yaml格式,(saltstack、elk、docker、docker-compose、k8s都会使用到yaml格式。&am…...
sqlmap中文文档
这是 sqlmap -hh的翻译,后续可能会对参数进行详细的示例 sqlmap 普通选项 -h, --help # 显示基本帮助信息并退出 -hh # 详细帮助信息 --versino # 版本 -v # 日志详细级别 0-60:只显示python错误以及严重的信息。1:同时显示基本信…...
【C++模拟实现】vector的模拟实现
【C模拟实现】vector的模拟实现 目录 【C模拟实现】vector的模拟实现vector模拟实现的标准代码vector模拟实现中的要点insert和erase会涉及到迭代器失效的问题vector深度剖析关于模版template< class InputIterator >使用memcpy拷贝问题 作者:爱写代码的刚子 …...
go学习part21(3)redis连接池
连接池 1.介绍 每次使用数据就就建立链接再关闭可以,但是如果有大量客户端频繁请求连接,大量创建连接和关闭会非常耗费资源。 所以就建立一个连接池,里面存放几个不关闭的连接,谁要用就分配给谁。 说明:通过Golang 对 Redis操…...
乐理-笔记
乐理笔记整理 1、前言2、认识钢琴键盘及音名3、升降号、还原号4、如何区分同一音名的不同键?5、各类音符时值的关系6、歌曲拍号7、拍号的强弱规律8、歌曲速度(BPM)9、附点音符10、三连音12、唱名与简谱数字13、自然大调(白键&…...
java八股文面试[数据库]——B树和B+树的区别
B树是一种树状数据结构,它能够存储数据、对其进行排序并允许以O(logn)的时间复杂度进行查找、顺序读取、插入和删除等操作。 1、B树的特性 B树中允许一个结点中包含多个key,可以是3个、4个、5个甚至更多,并不确定,需要看具体的实…...
2、Nginx 安装
文章目录 2、Nginx 安装2.1 官网下载2.2 安装 nginx2.2.1 第一步2.2.2 第二步2.2.3 第三步,安装 nginx2.2.4 第四步,修改防火漆规则 【尚硅谷】尚硅谷Nginx教程由浅入深 志不强者智不达;言不信者行不果。 2、Nginx 安装 2.1 官网下载 nginx…...
AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...
