当前位置: 首页 > news >正文

设计模式行为模式-命令模式

文章目录

  • 前言
  • 定义
  • 结构
  • 工作原理
  • 优点
  • 适用场景
  • 消息队列模式Demo实现
  • 分写业务
  • 总结

前言

定义

命令模式(Command Pattern)是一种行为型设计模式,用于将请求封装为对象,从而使你可以使用不同的请求、队列或者日志请求来参数化其他对象。这样可以实现请求的参数化操作、队列化和日志化,且能够支持撤销操作。

结构

命令模式由以下几个核心组件组成:

  • 命令(Command): 定义了执行操作的接口。通常包含一个 execute() 方法,该方法在调用时会触发接收者执行相关操作。
  • 具体命令(Concrete Command):实现命令接口,并将真正的操作委托给接收者。
  • 接收者(Receiver):负责执行实际的操作。具体命令将请求委托给接收者完成具体的业务逻辑。
  • 调用者(Invoker):负责调用命令并触发执行操作的方法。
  • 客户端(Client):创建具体命令,并将其与接收者进行绑定。
    在这里插入图片描述

工作原理

  1. 客户端创建一个具体命令,并将其与接收者(执行操作的对象)进行绑定。
  2. 调用者接收到命令后,将其存储起来,可以将命令存储在队列中,以支持撤销和重做操作。
  3. 调用者根据需要调用命令的 execute() 方法。该方法会将请求传递给接收者,由接收者执行实际的操作。
  4. 接收者执行命令所指定的操作,并完成相应的业务逻辑。

优点

  • 解耦调用者和接收者:调用者无需了解命令的具体实现,只需调用命令对象的方法来触发执行。
  • 支持撤销和重做:通过存储命令的历史记录,可以方便地进行撤销和重做操作。
  • 支持事务:可以通过一系列的命令组合形成事务,保证一组操作的原子性。

适用场景

  • 需要将请求和执行操作解耦的情况。
  • 需要支持撤销、重做、事务等操作的场景。
  • 需要将一组操作组织成具体的命令队列或日志操作。

消息队列模式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() 方法处理消息。
在这里插入图片描述

分写业务

这个业务代码实现了一个简单的消息队列框架。下面对代码进行逐步解释:

  1. 首先,定义了一个消息接口 IMessage,其中包含了 execute() 方法用于执行具体的消息处理操作。

  2. 接着,实现了具体的消息类 ConcreteMessage,它实现了 IMessage 接口,并在 execute() 方法中执行具体的消息处理逻辑。在本例中,处理逻辑简单地打印出消息内容。

  3. 然后,定义了消息队列类 MessageQueue,使用 Queue 数据结构来保存消息对象。它提供了入队(enqueue())、出队(dequeue())和判断队列是否为空(isEmpty())的方法。

  4. 接下来,定义了消费者类 Consumer,它通过循环从消息队列中取出消息,并调用消息对象的 execute() 方法进行处理。

  5. 最后,定义了生产者类 Producer,它负责向消息队列中发送消息。通过调用 sendMessage() 方法,生产者创建一个具体的消息对象并将其加入到消息队列中,同时打印出发送的消息内容。

在客户端代码的 main() 方法中,完成以下步骤:

  1. 创建了一个消息队列对象 messageQueue

  2. 创建了消费者对象 consumer,并启动一个新线程来执行消费者的消息处理逻辑。

  3. 创建了生产者对象 producer,通过调用 sendMessage() 方法发送了三条消息。

  4. 最后,通过调用 join() 方法等待消费者线程处理完所有消息。

总结

这个示例展示了如何使用 Java 实现一个简单的消息队列框架。通过将消息封装为对象,我们可以方便地在生产者和消费者之间进行消息的传递和处理。使用消息队列框架可以实现解耦和异步处理的优势。生产者负责发送消息,消费者负责处理消息,它们通过共享的消息队列进行通信。通过多线程的方式,我们可以实现并发的消息处理,提高系统的吞吐量和响应性能。

相关文章:

设计模式行为模式-命令模式

文章目录 前言定义结构工作原理优点适用场景消息队列模式Demo实现分写业务总结 前言 定义 命令模式&#xff08;Command Pattern&#xff09;是一种行为型设计模式&#xff0c;用于将请求封装为对象&#xff0c;从而使你可以使用不同的请求、队列或者日志请求来参数化其他对象…...

Linux-安装redis6.2.1及主备复制模式(replication)

Linux-安装redis6.2.1 下载redis6.2.1资源上传至安装目录解压及编译解压修改名称编译 修改配置文件主节点从节点 启动及测试启动主节点从节点 测试 下载redis6.2.1资源 地址》https://redis.io/download/ 上传至安装目录 例&#xff1a;/data/replication/ 解压及编译 解…...

新手做TikTok适合哪些类目?

现在很多小伙伴争先恐后想要在TikTok入驻&#xff0c;开店开直播带货赚钱&#xff0c;但是又怕自己是小白&#xff0c;不好拿捏这个平台。TikTok平台&#xff0c;适合小白做吗&#xff1f;现在tiktok千亿级的流量还处于蓝海阶段&#xff0c;想入局要趁早。那么肯定又有小伙伴疑…...

Open3D(C++) 点云格网分块

目录 一、算法概述二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、算法概述 点云格网分块是点云二维格网化的一个具体应用案例,与Open3D (C++) 使用点云创建数字高程模型DEM类似,对每个格…...

基于springboot跟redis实现的排行榜功能(实战)

概述 前段时间&#xff0c;做了一个世界杯竞猜积分排行榜。对世界杯64场球赛胜负平进行猜测&#xff0c;猜对1分&#xff0c;错误0分&#xff0c;一人一场只能猜一次。 1.展示前一百名列表。 2.展示个人排名(如&#xff1a;张三&#xff0c;您当前的排名106579)。 一.redis so…...

Mongodb常见操作命令

一、登录相关以及启动 启动服务mongodb&#xff1a; cd /usr/local/mongodb/bin ./mongod -f /data/mongodb/mongodb1.conf./mongod -f /data/mongodb/mongodb2.conf./mongod -f /data/mongodb/mongodb3.conf 登录mongodb数据库&#xff08;mongodb默认端口:27017&#xff0…...

springcloud-nacos简述

Spring Cloud alibaba: nacos服务注册中心&#xff0c;配置中心 服务注册中心 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实现图&#xff1a; 因为JWT的无状态&#xff0c;服务端无法在使用过程中主动废止某个 token&#xff0c;或者更改 token 的权限…...

Docker进入容器出现bash: vi: command not found

&#x1f388;1 参考文档 docker基础容器中bash: vi: command not found问题解决 | 你邻座的怪同学-CSDN &#x1f50d;2 问题描述 在使用 Docker 容器时&#xff0c;有时候里边没有安装vim&#xff0c;敲vim命令时提示说&#xff1a;vim: command not found。 这个时候就需要…...

Linux_6_文件查找与打包压缩

目录 文件查找与打包压缩1文件查找1.1 locate1.2 find1.2.1 指定搜索目录层级1.2.2对每个目录先处理目录内的文件&#xff0c;再处理目录本身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 等 点击无反应不回显问题解决

如上图&#xff0c;编辑回显正常&#xff0c;但是时间控件在拖动过程中时间不会跟随改变。 解决办法&#xff1a; <el-date-picker input"onInput()" ...><el-input input"onInput()" ...>js中onInput() {this.$forceUpdate();},...

Ansible学习笔记12

playbook&#xff1a; playbook&#xff08;剧本&#xff09;&#xff1a;是ansible用于配置、部署和管理被控节点的剧本&#xff0c;用于Ansible操作的编排。 使用的是yaml格式&#xff0c;&#xff08;saltstack、elk、docker、docker-compose、k8s都会使用到yaml格式。&am…...

sqlmap中文文档

这是 sqlmap -hh的翻译&#xff0c;后续可能会对参数进行详细的示例 sqlmap 普通选项 -h, --help # 显示基本帮助信息并退出 -hh # 详细帮助信息 --versino # 版本 -v # 日志详细级别 0-60&#xff1a;只显示python错误以及严重的信息。1&#xff1a;同时显示基本信…...

【C++模拟实现】vector的模拟实现

【C模拟实现】vector的模拟实现 目录 【C模拟实现】vector的模拟实现vector模拟实现的标准代码vector模拟实现中的要点insert和erase会涉及到迭代器失效的问题vector深度剖析关于模版template< class InputIterator >使用memcpy拷贝问题 作者&#xff1a;爱写代码的刚子 …...

go学习part21(3)redis连接池

连接池 1.介绍 每次使用数据就就建立链接再关闭可以&#xff0c;但是如果有大量客户端频繁请求连接&#xff0c;大量创建连接和关闭会非常耗费资源。 所以就建立一个连接池&#xff0c;里面存放几个不关闭的连接&#xff0c;谁要用就分配给谁。 说明:通过Golang 对 Redis操…...

乐理-笔记

乐理笔记整理 1、前言2、认识钢琴键盘及音名3、升降号、还原号4、如何区分同一音名的不同键&#xff1f;5、各类音符时值的关系6、歌曲拍号7、拍号的强弱规律8、歌曲速度&#xff08;BPM&#xff09;9、附点音符10、三连音12、唱名与简谱数字13、自然大调&#xff08;白键&…...

java八股文面试[数据库]——B树和B+树的区别

B树是一种树状数据结构&#xff0c;它能够存储数据、对其进行排序并允许以O(logn)的时间复杂度进行查找、顺序读取、插入和删除等操作。 1、B树的特性 B树中允许一个结点中包含多个key&#xff0c;可以是3个、4个、5个甚至更多&#xff0c;并不确定&#xff0c;需要看具体的实…...

2、Nginx 安装

文章目录 2、Nginx 安装2.1 官网下载2.2 安装 nginx2.2.1 第一步2.2.2 第二步2.2.3 第三步&#xff0c;安装 nginx2.2.4 第四步&#xff0c;修改防火漆规则 【尚硅谷】尚硅谷Nginx教程由浅入深 志不强者智不达&#xff1b;言不信者行不果。 2、Nginx 安装 2.1 官网下载 nginx…...

最适合 AI 的 Python Web 框架

迷途小书童的 Note 读完需要 4分钟 速读仅需 2 分钟 1 简介 本文将介绍 Gradio 库&#xff0c;它是 Python 的一个 web 框架&#xff0c;可以帮助我们快速构建交互式 AI 应用。我们将了解 Gradio 的应用场景、基本原理、功能介绍&#xff0c;并通过一个代码示例来演示如何使用 …...

算法通关村第十八关——回溯

回溯很大感觉就是多重递归&#xff0c;在递归的题目中&#xff0c;例如斐波那契数列&#xff0c;只需要考虑当前情况以及他的子情况。而在回溯中&#xff0c;要进行很多次递归&#xff0c;并且要对条件进行处理。 LeetCode257:给你一个二叉树的根节点root,按任意顺序&#xff…...

使用kafka还在依赖Zookeeper,kraft模式了解下

Kafka的Kraft模式 概述 ​ Kafka是一种高吞吐量的分布式发布订阅消息系统&#xff0c;它可以处理消费者在网站中的所有动作流数据。其核心组件包含Producer、Broker、Consumer&#xff0c;以及依赖的Zookeeper集群。其中Zookeeper集群是Kafka用来负责集群元数据的管理、控制器…...

【100天精通Python】Day52:Python 数据分析_Numpy入门基础与数组操作

目录 1 NumPy 基础概述 1.1 NumPy的主要特点和功能 1.2 NumPy 安装和导入 2 Numpy 数组 2.1 创建NumPy数组 2.2 数组的形状和维度 2.3 数组的数据类型 2.4 访问和修改数组元素 3 数组操作 3.1 数组运算 3.2 数学函数 3.3 统计函数 4 数组形状操作 4.1 重塑数组形…...

Day01-Java基础语法

目录 1. 人机交互 1.1 什么是cmd&#xff1f; 1.2 如何打开CMD窗口&#xff1f; 1.3 常用CMD命令 1.4 CMD练习 1.5 环境变量 2. Java概述 1.1 Java是什么&#xff1f; 1.2下载和安装 1.2.1 下载 1.2.2 安装 1.2.3 JDK的安装目录介绍 1.3 HelloWorld小案例 2.3.1 …...

代码随想录二刷day06

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、力扣242. 有效的字母异位词二、力扣349. 两个数组的交集三、力扣202. 快乐数四、力扣1两数之和 前言 一、力扣242. 有效的字母异位词 class Solution {pub…...

可扩展的Blender插件开发汇总

成熟的 Blender 3D 插件是令人惊奇的事情。作为 Python 和 Blender 的新手,我经常发现自己被社区中的人们创造的强大的东西弄得目瞪口呆。坦率地说,其中一些包看起来有点神奇,当自我怀疑或冒名顶替综合症的唠叨声音被打破时,很容易想到“如果有人能做出可以做xxx的东西就好…...

2023_Spark_实验二:IDEA安装及配置

一、下载安装包 链接&#xff1a;百度网盘 请输入提取码 所在文件夹&#xff1a;大数据必备工具--》开发工具(前端后端)--》后端 下载文件名称&#xff1a;ideaIU-2019.2.3.exe &#xff08;喜欢新版本也可安装新版本&#xff0c;新旧版本会存在部分差异&#xff09; IDEA …...

小赢科技,寻找金融科技核心价

如果说金融是经济的晴雨表&#xff0c;是通过改善供给质量以提高经济质量的切入口&#xff0c;那么金融科技公司&#xff0c;就是这一切行动的推手。上半年&#xff0c;社会经济活跃程度提高背后&#xff0c;金融科技公司既是奉献者&#xff0c;也是受益者。 8月29日&#xff0…...

NAT与代理服务器

1.DNS Domain Name System 是一整套从域名映射到IP的系统&#xff08;把域名转化为IP地址&#xff09; 2.域名简介 3.周鸿祎 傅盛 4.ICMP协议 用来网络故障排查原因 草图理解“位置” ping ICMP 是绕过TCP UDP传输协议的&#xff0c;没有端口号 traceroute 5.NAT技术 N…...