【设计模式】Java 设计模式之模板命令模式(Command)

命令模式(Command)的深入分析与实战解读

一、概述
命令模式是一种将请求封装为对象从而使你可用不同的请求把客户端与接受请求的对象解耦的模式。在命令模式中,命令对象使得发送者与接收者之间解耦,发送者通过命令对象来执行请求,而接收者则执行命令对象的操作。

二、模式结构
命令模式主要包含四个角色:

  1. 抽象命令类(Command):声明执行操作的接口。
  2. 具体命令类(ConcreteCommand):实现抽象命令接口的具体命令类,它持有接收者对象,并调用接收者的相应操作以执行请求。
  3. 接收者类(Receiver):执行具体操作的类。
  4. 调用者类(Invoker):要求命令对象执行请求。

三、实现方式
命令模式的实现可以通过接口或抽象类来定义命令的行为,具体命令类实现这些行为,并持有对接收者的引用。调用者通过命令对象来调用接收者的方法,而无需直接知道接收者的具体类型。

在这里插入图片描述
直接请求,依赖关系太强。Handler类的改变,需要修改ListView。
通过增加Command抽象命令类,将不符合抽象编程的handler 调用,转为抽象编程。在这里插入图片描述

四、代码示例

// 抽象命令类
public interface Command {void execute();
}// 具体命令类
public class ConcreteCommand implements Command {private Receiver receiver;public ConcreteCommand(Receiver receiver) {this.receiver = receiver;}@Overridepublic void execute() {receiver.action();}
}// 接收者类
public class Receiver {public void action() {System.out.println("Receiver action performed.");}
}// 调用者类
public class Invoker {private Command command;public void setCommand(Command command) {this.command = command;}public void executeCommand() {command.execute();}
}

五、优点

  1. 解耦:命令模式将请求与具体实现解耦,使得调用者与接收者之间不再直接依赖。
  2. 灵活性和扩展性:可以很容易地添加新的命令类型,无需修改现有代码。
  3. 可撤销和恢复:可以在命令对象中实现撤销和恢复操作。

六、缺点

  1. 可能产生过多具体命令类:对于每一个请求都可能需要一个具体命令类,导致系统复杂性增加。
  2. 可能不适合所有情况:在一些简单场景下,引入命令模式可能增加不必要的复杂性。

七、应用场景

  1. GUI应用:如按钮点击事件处理,每个按钮对应一个命令对象。
  2. 事务处理:将事务封装为命令对象,便于管理事务的执行和撤销。
  3. 日志记录:将日志记录操作封装为命令对象,便于灵活配置日志记录行为。

八、实战解读
以GUI应用为例,假设有一个“撤销”按钮,用户点击该按钮时希望撤销上一步的操作。通过命令模式,可以将每个操作封装为一个命令对象,并维护一个命令历史栈。当用户点击“撤销”按钮时,从栈中弹出最后一个命令并执行其撤销操作。

九、注意事项
在使用命令模式时,需要注意避免过度使用,以免增加不必要的复杂性。同时,要确保命令对象的执行和撤销操作是安全的,不会导致系统状态不一致或数据损坏。

十、命令模式的可维护性
命令模式使得请求的处理逻辑可以被封装和复用,这大大提高了系统的可维护性。当需要修改某个操作的行为时,只需修改相应的命令类,而无需影响其他部分的代码。

十一、命令队列和宏命令
命令模式支持将多个命令组合成一个命令队列或宏命令,从而一次性执行多个操作。这为用户提供了更高级别的操作灵活性,并简化了复杂操作的执行过程。

十二、命令模式与策略模式的关系
命令模式与策略模式在某种程度上具有相似性,都涉及到行为的封装和替换。然而,命令模式更侧重于请求的处理和封装,而策略模式则更侧重于算法的封装和替换。在实际应用中,可以根据具体需求选择使用哪种模式。

十三、命令模式的线程安全性
在多线程环境中,命令模式可以确保每个命令对象的执行是线程安全的。通过将命令对象设计为无状态的,可以避免多线程间的数据竞争和状态不一致问题。

十四、命令模式的扩展性
命令模式具有良好的扩展性,可以通过添加新的命令类来扩展系统的功能。这使得系统在面对新的需求或变更时能够更加灵活地应对,降低了系统的维护成本。

综上所述,命令模式不仅提高了系统的可维护性和可扩展性,还为多线程环境下的请求处理提供了线程安全的保障。同时,它与策略模式等其他设计模式相互配合,可以构建出更加灵活和健壮的系统架构。

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

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

相关文章

嵌套循环实现九九乘法表

大家好&#xff1a; 衷心希望各位点赞。 您的问题请留在评论区&#xff0c;我会及时回答。 案例描述 利用嵌套循环&#xff0c;实现九九乘法表。 代码 #include <iostream> #include <Windows.h>using namespace std;int main(void) {//外层循环执行一次&#…

v-bind 绑定 class 与 style 基础用法

使用 v-bind 指令绑定 class 和 style 时语法相对复杂一些&#xff0c;这两者是可以互相替代的&#xff0c;均用于响应更新HTML元素的属性&#xff0c; v-bind 绑定 class 属性可以改写成绑定 style 属性&#xff0c;只是 css 属性位置变了而已。 1. 绑定 class 属性 1.1 数组…

学了 Python 但又感觉没学 Python 不如重学 Python - day4(数据类型:列表)

目录 1、创建列表 2、列表基本操作 3、索引与分片 4、矩阵 5、常用列表方法 &#xff08;1&#xff09;append 与 extend 方法 &#xff08;2&#xff09;insert 方法 &#xff08;3&#xff09;remove 与 pop 方法 &#xff08;4&#xff09;del 语句与 clear 方法 …

conda创建环境网络报错解决办法

文章目录 一、报错示例&#xff1a;二、解决办法&#xff1a;2.1 查看配置 conda config --show-sources2.2 修改文件 /home/XXXX/.condarc 一、报错示例&#xff1a; UnavailableInvalidChannel: HTTP 404 NOT FOUND for channel nvidia <http://mirrors.tuna.tsinghua.ed…

【机器学习-05】模型的评估与选择

在前面【机器学习-01】机器学习基本概念与建模流程的文章中我们已经知道了机器学习的一些基本概念和模型构建的流程&#xff0c;本章我们将介绍模型训练出来后如何对模型进行评估和选择等 1、 误差与过拟合 学习器对样本的实际预测结果与真实值之间的差异&#xff0c;我们称之…

一次完整的 HTTP 请求所经历的步骤

1&#xff1a; DNS 解析(通过访问的域名找出其 IP 地址&#xff0c;递归搜索)。 2&#xff1a; HTTP 请求&#xff0c;当输入一个请求时&#xff0c;建立一个 Socket 连接发起 TCP的 3 次握手。如果是 HTTPS 请求&#xff0c;会略微有不同。 3&#xff1a; 客户端向服务器发…

Redis 搭建主从集群

文章目录 1. 主从集群架构1.1 准备实例和配置1.2 启动1.3 开启主从关系1.4 测试 2. 主从同步原理2.1 全量同步2.2 增量同步repl_backlog原理 2.3 主从同步优化小结 单节点的 Redis 并发能力有限&#xff0c;要进一步提高 Redis 的并发能力&#xff0c;就需要搭建主从集群&#…

杰发科技AC7801——Flash数据读取

0. 简介 因为需要对Flash做CRC校验&#xff0c;第一步先把flash数据读出来。 1. 代码 代码如下所示 #include "ac780x_eflash.h" #include "string.h" #define TestSize 1024 ///< 4K #define TestAddressStart 0x08000000 uint8_t Data[7000]; int…

<DFS剪枝>数字王国之军训排队

DFS剪枝 其实就是将搜索过程一些不必要的部分直接剔除掉。 剪枝是回溯法的一种重要优化手段&#xff0c;往往需要先写一个暴力搜索&#xff0c;然后找到某些特殊的数学关系&#xff0c;或者逻辑关系&#xff0c;通过它们的约束让搜索树尽可能浅而小&#xff0c;从而达到降低时间…

MAC地址(静态、黑洞、优先级)

拓扑图 配置 1&#xff09;静态MAC地址配置 mac-address learning disable命令用来关闭MAC地址学习功能。 关闭MAC地址学习功能后&#xff0c;设备将不会再从该接口学习新的MAC地址。关闭MAC地址学习后可配置的动作有discard和forward。 关闭MAC地址学习功能的缺省动作为fo…

NSS [SWPUCTF 2022 新生赛]ez_ez_unserialize

NSS [SWPUCTF 2022 新生赛]ez_ez_unserialize 开题&#xff0c;直接给了题目源码。 简单看了一下&#xff0c;题目告诉我们flag在哪&#xff0c;而且类中有高亮文件方法。怎么拿flag已经很明显了。关键点在于__weakup()魔术方法固定死了我们高亮的文件。所以这题只需要绕过__w…

【故障排查】10分钟解决Quartz重复调度的疑难杂症

我司使用Apache DolphinScheduler作为调度框架很久了&#xff0c;感兴趣的小伙伴可以看看这些干货文章&#xff1a; 因为之前监控到会出现重复的调度的问题&#xff0c;所以此文记录排查重复调度问题的全过程&#xff0c;希望对社区其他的小伙伴能够起到抛砖引玉的作用&#x…

【学习】python函数语法(面像对象、封装函数)

阅读开源深度学习源码的时候&#xff0c;使用到了很多封装函数以及Python的高级语法&#xff0c;看起来很混乱很痛苦很困难。对python函数语法做个总结&#xff01;&#xff01;&#xff01; Table of Contents 熟练Python语法&#xff0c;尤其是函数参数、迭代器与生成器、函…

使用Redis做缓存的小案例

如果不了解Redis&#xff0c;可以查看本人博客&#xff1a;Redis入门 Redis基于内存&#xff0c;因此查询速度快&#xff0c;常常可以用来作为缓存使用&#xff0c;缓存就是我们在内存中开辟一段区域来存储我们查询比较频繁的数据&#xff0c;这样&#xff0c;我们在下一次查询…

C#,图论与图算法,有向图(Directed Graph)的环(Cycle)的普通判断算法与源代码

1 检查该图是否包含循环 给定一个有向图,检查该图是否包含循环。如果给定的图形至少包含一个循环,则函数应返回true,否则返回false。 方法:深度优先遍历可用于检测图中的循环。连接图的DFS生成树。只有当图中存在后缘时,图中才存在循环。后边是从节点到自身(自循环)或…

[视觉基础知识]: img to bev # include bev seg

参考&#xff1a;https://towardsdatascience.com/monocular-birds-eye-view-semantic-segmentation-for-autonomous-driving-ee2f771afb59 有源传感器&#xff08;lidar or radar&#xff09;得到的数据&#xff0c;天然就是一种bev表示&#xff08;x-y平面&#xff09;&#…

想速成AD?凡亿教育正式上线《Altium Designer 24:150讲操作速成实战课程》

随着电子技术的不断发展,芯片生产工艺迭代更新,印制电路板(PCB)结构日益复杂,从最早的单片机到双面板,再到复杂的多层板结构,电路板上的布线密度越来越高。 同时,随着DSP、ARM、FPGA、DDR等高速逻辑元件的应用,PCB的信号完整性和抗干扰性能显得尤为重要,光靠EDA软件的自动布线…

LeetCode每日一题 翻转二叉树(二叉树)

题目描述 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1] 示例 2&#xff1a; 输入&#xff1a;root [2,1,3] 输出&#xff1a;[2,3,1]示…

Mistral AI vs. Meta:两大 Top 开源模型的对比

编者按&#xff1a; 随着大模型的不断升级和参数量的持续扩大&#xff0c;越来越多人开始重视大模型存在的硬件资源要求高、碳排放量较大等问题。如何在保持模型性能的同时&#xff0c;降低计算成本和资源消耗&#xff0c;成为了业界一个迫切需要解决的问题。 我们今天为大家带…

Servlet使用

文章目录 简介一、快速入门二、Servlet 执行流程三、Servlet 生命周期四、Servlet 方法介绍五、Servlet 体系结构六、Servlet urlPattern配置七、XML 配置方式编写 Servlet 简介 一、快速入门 <dependencies><dependency><groupId>javax.servlet</groupId…