命令模式(行为型)
目录
一、前言
二、命令模式
三、总结
一、前言
命令模式(Command Pattern)是一种行为型设计模式,命令模式将一个请求封装为一个对象,从而可以用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
命令模式由以下角色组成:
Command(命令):
该角色定义了执行操作的接口。通常包含一个执行操作的方法,如
execute()。命令对象可能会携带执行操作所需的参数。Concrete Command(具体命令):
该角色实现了命令接口,对具体的操作进行了实现。具体命令对象将一个接收者对象绑定到一个动作,并负责调用接收者的相应方法来执行请求。
Receiver(接收者):
该角色实际执行操作的对象。命令对象会将请求委托给接收者来执行实际的操作。
Invoker/Client(调用者/客户端):
该角色创建命令对象并将其发送给接收者。调用者不需要了解命令是如何执行的,它只需要发送请求。
整个命令模式的结构图:

二、命令模式
比如在餐馆就餐,我们会先向服务员点单,下单后服务员通知后厨进行制作,这种就可以用命令模式进行演示。Receiver可以当做是具体制作食物的厨师,Invoker可以当做是服务员进行调用,Command理解成每一个菜单,也就是发出的命令。
先创建厨师Receiver类:
public class Receiver {public void actionOne(){System.out.println("制作食物one");}public void actionTwo(){System.out.println("制作食物two");}public void actionThree(){System.out.println("制作食物three");}
}
创建抽象命令Command:
public interface Command {void execute();
}
创建菜单具体的命令:
public class ConcreteCommandOne implements Command{private Receiver receiver;public ConcreteCommandOne(Receiver receiver) {this.receiver = receiver;}@Overridepublic void execute() {receiver.actionOne();}
}public class ConcreteCommandTwo implements Command{private Receiver receiver;public ConcreteCommandTwo(Receiver receiver) {this.receiver = receiver;}@Overridepublic void execute() {receiver.actionTwo();}
}public class ConcreteCommandThree implements Command{private Receiver receiver;public ConcreteCommandThree(Receiver receiver) {this.receiver = receiver;}@Overridepublic void execute() {receiver.actionThree();}
}
创建服务员Invoker类:
public class Invoker {private List<Command> commands = new ArrayList<>();public void setCommand(Command command){commands.add(command);}public void removeCommand(Command command){commands.remove(command);System.err.println("取消订单");}public void call(){for (Command command : commands){command.execute();}}
}
客户端调用类:
public class Client {public static void main(String[] args) {Receiver receiver = new Receiver();Command commandOne = new ConcreteCommandOne(receiver);Command commandTwo = new ConcreteCommandTwo(receiver);Command commandThree = new ConcreteCommandThree(receiver);Invoker invoker = new Invoker();invoker.setCommand(commandOne);invoker.setCommand(commandTwo);invoker.setCommand(commandThree);invoker.removeCommand(commandTwo);invoker.call();}
}
执行结果:

可以看出client创建不同的命令,通过invoker将命令设置进去,也可以通过invoker取消命令,最后invoker通知进行调用。
三、总结
优点与缺点:
优点:
解耦请求发送者和接收者:
命名模式将请求封装成一个对象,使得发送者和接收者之间的解耦程度增加。发送者只需要知道如何发送命令,而不需要了解命令是如何被执行的。
支持撤销和重做操作:
由于命令对象封装了对接收者的调用,因此可以轻松地实现撤销和重做操作,只需保留历史命令对象即可。
增加新的命令:
通过添加新的命令类,可以轻松地扩展命令模式,而无需修改现有的客户端代码。
支持组合命令:
可以通过组合多个命令对象来执行复杂的操作,从而实现更高级的功能。
缺点:
类爆炸:
在系统中可能会产生大量的具体命令类,如果命令种类过多,可能会导致类爆炸,增加系统的复杂性。
增加调试难度:
由于命令模式涉及多个对象之间的交互,因此调试可能会变得更加复杂。
应用场景:
GUI应用程序:
命令模式常用于实现菜单和工具栏按钮的操作。每个菜单项或按钮可以表示一个命令,当用户点击时,该命令将被执行。
任务队列:
命令模式可以用于实现任务队列,例如,在操作系统中,可以将用户的操作封装成命令对象,然后将它们放入队列中以便逐个执行。
日志系统:
命令模式可以用于实现日志系统,将所有操作封装成命令对象,并在执行时记录相关的日志信息。
撤销/重做功能:
命令模式很适合实现撤销和重做功能,因为每个命令对象都可以保存执行时的状态,从而支持撤销和重做操作。
相关文章:
命令模式(行为型)
目录 一、前言 二、命令模式 三、总结 一、前言 命令模式(Command Pattern)是一种行为型设计模式,命令模式将一个请求封装为一个对象,从而可以用不同的请求对客户进行参数化;对请求排队或记录请求日志,以…...
韩雪医生针药结合效果好 患者赠送锦旗表感谢
任先生长年献血身体出现不适,身上多处发黑发冷,伴随疼痛,而且还有慢性腹泻的症状。他曾前往苏州各大医馆做过检查,均查不出异常,但身体确实不舒服,面色晦暗。 后来他来到李良济,求诊于韩雪医生。…...
【队列、堆、栈 解释与区分】
文章目录 概要队列(Queue)定义特性应用场景 堆(Heap)定义特性应用场景 栈(Stack)定义特性应用场景 总结 概要 队列、堆和栈是三种常见的数据结构,它们各自具有不同的特性和应用场景。下面是对这…...
NTP网络时间服务器_安徽京准电钟
NTP网络时间服务器_安徽京准电钟 NTP网络时间服务器_安徽京准电钟 概述 NTP网络时间服务器是一款支持NTP和SNTP网络时间同步协议,高精度、大容量、高品质的高科技时钟产品。 NTP网络时间服务器设备采用冗余架构设计,高精度时钟直接来源于北斗、GPS系统中…...
Java:爬虫框架
一、Apache Nutch2 【参考地址】 Nutch 是一个开源Java 实现的搜索引擎。它提供了我们运行自己的搜索引擎所需的全部工具。包括全文搜索和Web爬虫。 Nutch 致力于让每个人能很容易, 同时花费很少就可以配置世界一流的Web搜索引擎. 为了完成这一宏伟的目标, Nutch必须能够做到…...
ChatGPT基本原理详细解说
ChatGPT基本原理详细解说 引言 在人工智能领域,自然语言处理(NLP)一直是研究的热点之一。随着技术的发展,我们见证了从简单的聊天机器人到复杂的语言模型的演变。其中,ChatGPT作为一项突破性技术,以其强大…...
Java日期时间处理深度解析:从Date、Calendar到SimpleDateFormat
粉丝福利:微信搜索「万猫学社」,关注后回复「电子书」,免费获取12本Java必读技术书籍。 Java中的日期和时间处理 在Java中,日期和时间的处理一直是一个复杂而繁琐的任务。那么,为什么会这样呢?让我们先来看…...
Flutter 中的 CupertinoUserInterfaceLevel 小部件:全面指南
Flutter 中的 CupertinoUserInterfaceLevel 小部件:全面指南 Flutter 是一个功能强大的 UI 框架,由 Google 开发,允许开发者使用 Dart 语言构建跨平台的移动、Web 和桌面应用。在 Flutter 的 Cupertino(iOS 风格)组件…...
区块链学习记录01
在学习过程中所遇到的问题,及其解。 Q:区块链中分布式账本的存在,让所有人都知道资金的变动吗? A:区块链中的分布式账本确实让参与网络的所有节点都能够了解账户之间的资金变动。这是因为区块链是一个分布式数据库,其中包含着所…...
python--装饰器
[掌握]装饰器入门 语法糖 目标:掌握装饰器的快速使用。 装饰器本质上就是闭包,但装饰器有特殊作用,那就是:在不改变原有函数的基础上,给原有函数增加额外功能。 定义装饰器: def outer([外面参数列表]):…...
Docker:定义未来的软件部署
1. 概述 Docker,这个在技术圈里频频被提及的名词,实际上是一种开源的容器化技术。它允许开发者将应用程序及其依赖打包成一个标准化的单元——容器,确保应用在任何环境中都能够一致地运行。从开发者的本地机器到全球的云平台,Doc…...
ros常用环境变量
RMW层DDS实现 rti dds export RMW_IMPLEMENTATIONrmw_connextdds //rti dds 或者 RMW_IMPLEMENTATIONrmw_connextdds ros2 run ... export NDDS_QOS_PROFILES/qos.xml //配置qos文件fastdds export RMW_IMPLEMENTATIONrmw_fastrtps_cpp 或者 RMW_IMPLEMENTATIONrmw_fas…...
python学习 - 爬虫案例 - 爬取链接房产信息入数据库代码实例
#codingutf-8 #!/usr/bin/python # 导入requests库 import requests # 导入文件操作库 import os import re import bs4 from bs4 import BeautifulSoup import sys from util.mysql_DBUtils import mysql# 写入数据库 def write_db(param):try:sql "insert into house (…...
Git 完整操作之记录
目录 一 . Git 基本操作流程及示例代码 1. 初始化 Git 仓库 2. 克隆远程仓库 3. 检查当前状态 4. 添加文件到暂存区 5. 提交更改 6. 查看提交历史 7. 创建分支 8. 切换分支 9. 合并分支 10. 推送更改到远程仓库 11. 拉取远程仓库的更改 12. 回滚到上一个版本 二…...
mediaPlayer的内存泄露解决方法
MediaPlayer在Android中用于播放音频和视频。如果不正确管理,MediaPlayer可能会导致内存泄漏,尤其是当它被用于多个Activity或长时间播放时。以下是一些解决MediaPlayer内存泄漏的方法: ### 1. 及时释放资源 当MediaPlayer不再使用时&#x…...
delphi3层 delphi 3层
一、为DataSnap系统服务程序添加描述 procedure TServerContainer.ServiceAfterInstall(Sender: TService); var reg: TRegistry; begin reg : TRegistry.Create; try with reg do begin RootKey : HKEY_LOCAL_MACHINE; if OpenKey(SYSTEM/CurrentC…...
Python编程学习第一篇——制作一个小游戏休闲一下
到上期结束,我们已经学习了Python语言的基本数据结构,除了数值型没有介绍,数值型用的非常广,但也是最容易理解的,将在未来的学习中带大家直接接触和学习掌握。后续我们会开始学习这门语言的一些基础语法和编程技巧&…...
03--nginx架构实战
前言:这应该是nginx梳理的最后一章,写一些关于网站架构和网站上线的知识内容,主要是感觉到运维并不是单一方向的行业,这一章概念会有一些广泛,但是非常重要,都是这几年工作中遇到的情况,整理一下…...
【力扣第 400 场周赛】Leetcode 删除星号以后字典序最小的字符串
文章目录 1. 删除星号以后字典序最小的字符串 1. 删除星号以后字典序最小的字符串 题目链接 🍎 解题思路:遇到 *就删除一个字符,为了满足题意,要删除字典序最小的字符,那么假如有多个字典序最小的字符我们该删除哪个…...
Unity DOTS技术(九) BufferElement动态缓冲区组件
文章目录 一.简介二.例子 一.简介 在之前的学习中我们发现Entity不能挂载相同的组件的. 当我们需要用相同的组件时则可以使用.IBufferElementData接口 动态缓冲区组件来实现 二.例子 1.创建IBufferElementData组件 using Unity.Entities; using UnityEngine; //[GenerateAu…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
深度学习水论文:mamba+图像增强
🧀当前视觉领域对高效长序列建模需求激增,对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模,以及动态计算优势,在图像质量提升和细节恢复方面有难以替代的作用。 🧀因此短时间内,就有不…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...
消防一体化安全管控平台:构建消防“一张图”和APP统一管理
在城市的某个角落,一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延,滚滚浓烟弥漫开来,周围群众的生命财产安全受到严重威胁。就在这千钧一发之际,消防救援队伍迅速行动,而豪越科技消防一体化安全管控平台构建的消防“…...
面试高频问题
文章目录 🚀 消息队列核心技术揭秘:从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"?性能背后的秘密1.1 顺序写入与零拷贝:性能的双引擎1.2 分区并行:数据的"八车道高速公路"1.3 页缓存与批量处理…...
20250609在荣品的PRO-RK3566开发板的Android13下解决串口可以执行命令但是脚本执行命令异常的问题
20250609在荣品的PRO-RK3566开发板的Android13下解决串口可以执行命令但是脚本执行命令异常的问题 2025/6/9 20:54 缘起,为了跨网段推流,千辛万苦配置好了网络参数。 但是命令iptables -t filter -F tetherctrl_FORWARD可以在调试串口/DEBUG口正确执行。…...
Shell 解释器 bash 和 dash 区别
bash 和 dash 都是 Unix/Linux 系统中的 Shell 解释器,但它们在功能、语法和性能上有显著区别。以下是它们的详细对比: 1. 基本区别 特性bash (Bourne-Again SHell)dash (Debian Almquist SHell)来源G…...
【JavaEE】万字详解HTTP协议
HTTP是什么?-----互联网的“快递小哥” 想象我们正在网上购物:打开淘宝APP,搜索“蓝牙耳机”,点击商品图片,然后下单付款。这一系列操作背后,其实有一个看不见的“快递小哥”在帮我们传递信息,…...
