设计模式浅析(六) ·命令模式

设计模式浅析(六) ·命令模式

日常叨逼叨

java设计模式浅析,如果觉得对你有帮助,记得一键三连,谢谢各位观众老爷😁😁


命令模式

概念

命令模式(Command Pattern)是一种行为设计模式,它允许将请求封装为一个对象,从而使你可以使用不同的请求将客户端与接收者解耦。命令模式也支持可撤销操作。

命令模式结构

命令模式(Command Pattern)的结构包含以下四个主要角色:

  1. Command(命令接口)
    • 定义了一个用于执行请求的接口。命令对象通常会持有接收者对象,并在调用时执行其上的操作。
  2. ConcreteCommand(具体命令类)
    • 实现了命令接口,通常会持有一个接收者对象,并定义了一个execute方法来执行请求。
    • 具体命令类知道如何执行与接收者相关联的动作,通常动作实现在接收者对象中,但命令对象决定了何时执行动作。
  3. Receiver(接收者)
    • 知道如何执行与命令相关联的具体操作。任何类都可能成为接收者,只要它能实现执行请求所需的操作。
  4. Invoker(调用者)
    • 也称为请求者,它负责调用命令对象来执行请求。
    • 调用者并不直接知道接收者的存在,也不直接与接收者交互。它通过命令对象来间接调用接收者。
  5. Client(客户端)
    • 创建具体命令对象,并设置给调用者。
    • 客户端负责组装命令对象,但并不直接调用接收者。
命令模式类图

请添加图片描述

示例

我们将模拟使用命令模式实现一个电视开关机Demo。电视遥控器操作有许多种,Demo实现电视的开机和关机两种操作,使用命令模式完成,方便后续其他操作模式的拓展。

根据上述命令模式的结构,首先创建一个命令接口,在抽象命令中,具有一个execute()方法,待会的具体命令将实现这个execute()方法。

//抽象命令接口
public interface Command {//命令执行void execute() throws InterruptedException;}

接着,我们需要定义一个命令的接收者,即负责处理命令的具体逻辑操作。在这个类中,我们定义了两种操作的方法,分别是on()off()。在两个方法中分别输出打开和关闭

public class TVCommandReceiver {public void on() throws InterruptedException {System.out.println("turn on tv");Thread.sleep(2000);System.out.println("now tv is on");}public void off() throws InterruptedException {System.out.println("turn off tv ");Thread.sleep(2000);System.out.println("now tv is off");}
}

然后实现具体的命令,CommandOn类实现了Command命令的execute()方法,并且管理了一个命令接收者实例,方便调用者Invoker进行调用

public class CommandOn implements Command{TVCommandReceiver tvCommandReceiver;public CommandOn(TVCommandReceiver tvCommandReceiver) {this.tvCommandReceiver = tvCommandReceiver;}@Overridepublic void execute() throws InterruptedException {tvCommandReceiver.on();}}

CommandOff与CommandOn相类似

public class CommandOff implements Command{TVCommandReceiver tvCommandReceiver;public CommandOff(TVCommandReceiver tvCommandReceiver) {this.tvCommandReceiver = tvCommandReceiver;}@Overridepublic void execute() throws InterruptedException {tvCommandReceiver.off();}}

最后,我们要实现一个命令的调用者即Invoker类,该类中含有添加命令和命令执行的具体逻辑。并管理了一个命令列表,方便记录历史。

在Invoker类中,我们实现了三个方法,分别是putCommand()runCommand()cancelCommand()putCommand()方法会将所有命令加入到命令列表中。而runCommand()方法将遍历所有命令,负责执行具体命令,cancelCommand()用于执行时取消某个命令。

public class Invoker {private List<Command> commandList = new ArrayList<>();/**** 添加命令* @param command*/public void putCommand(Command command) {commandList.add(command);}/**** 执行命令* @throws InterruptedException*/public void runCommand() throws InterruptedException {if (commandList.size() == 0) {System.out.println("no command input");}for (Command command : commandList) {command.execute();}commandList.clear();}/**** 取消命令* @param command*/public void cancelCommand(Command command) {if (commandList.size() == 0) {System.out.println("no command input");}int index = commandList.indexOf(command);if (index == -1) {System.out.println("no such command find ");} else {commandList.remove(index);System.out.println("command " + command + "has been canceled");}}
}

至此,尝试创建Client进行测试

public class Client {public static void main(String[] args) throws InterruptedException {//注册命令接收者TVCommandReceiver receiver = new TVCommandReceiver();//注册命令CommandOn tvOnCommand = new CommandOn(receiver);CommandOff tvOffCommand = new CommandOff(receiver);//添加命令Invoker invoker = new Invoker();invoker.putCommand(tvOnCommand);invoker.putCommand(tvOffCommand);//取消命令invoker.cancelCommand(tvOffCommand);//命令执行invoker.runCommand();}
}

执行结果:

command com.jerry.commandPattern.CommandOff@1b6d3586has been canceled
turn on tv
now tv is on

Process finished with exit code 0

至此,我们实现了简单的命令模式案例

优缺点
优点
  1. 降低耦合度:命令模式可以将请求者与接收者解耦,调用者只需要知道如何调用命令,而不需要知道命令的具体实现细节。
  2. 扩展性良好:增加或删除命令非常方便,满足“开闭原则”。由于增加新的命令类不会影响到其他类,因此系统具有良好的扩展性。
  3. 支持宏命令:命令模式可以与组合模式结合,将多个命令装配成一个组合命令(宏命令),从而可以一次性执行多个操作。
  4. 支持撤销和重做:命令模式可以与备忘录模式结合,实现命令的撤销与恢复操作,方便实现撤销(Undo)和重做(Redo)功能。
缺点
  1. 命令类过多:如果系统中有大量的命令,那么就需要创建大量的命令类,这可能会导致系统结构变得复杂,增加理解和维护的难度。
  2. 可能导致性能问题:如果命令的执行过程比较复杂,那么频繁地创建和销毁命令对象可能会对系统的性能产生负面影响。
  3. 客户端代码可能变得复杂:如果客户端需要创建和管理大量的命令对象,那么客户端代码可能会变得复杂和难以维护。

代码相关代码可以参考 代码仓库🌐

ps:本文原创,转载请注明出处


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

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

相关文章

异地组网什么原理?企业适合SDWAN异地组网吗?

深入解析异地组网及其对企业的影响 在数字化时代的洪流中&#xff0c;企业正经历着前所未有的变革。随着业务需求的多样化和全球化&#xff0c;传统的网络架构已无法满足现代企业的灵活性和效率要求。异地组网技术的兴起&#xff0c;特别是SD-WAN的应用&#xff0c;为企业提供…

git之远程操作

一.分布式版本控制系统 分布式版本控制系统通常也有⼀台充当“中央服务器”的电脑&#xff0c;但这个服务器的作⽤仅仅是⽤来⽅便“交换”⼤家的修改&#xff0c;没有它⼤家也⼀样⼲活&#xff0c;只是交换修改不⽅便⽽已。有了这个“中央服务器”的电脑&#xff0c;这样就不怕…

unity hub (第一部)初学配置

1、安装Unity Hub 2、设置中文 3、安装编辑器 4、新建项目 5、新建完成后进入编辑器 6、 编辑器设置中文 editPreferencesLanguages选择中文

(挖坑) Python调用图工具

基本效果 输入 #!/usr/bin/env pythonThis example demonstrates a simple use of pycallgraph.from pycallgraph import PyCallGraph from pycallgraph.output import GraphvizOutputclass Banana:def eat(self):passclass Person:def __init__(self):self.no_bananas()def…

港中文联合MIT提出超长上下文LongLoRA大模型微调算法

论文名称&#xff1a; LongLoRA: Efficient Fine-tuning of Long-Context Large Language Models 文章链接&#xff1a;https://arxiv.org/abs/2309.12307 代码仓库&#xff1a; https://github.com/dvlab-research/LongLoRA 现阶段&#xff0c;上下文窗口长度基本上成为了评估…

openlayers 行政区划 鼠标移入 圆扩散动画 打点

封装了一个类似全局动画控制器的类 用于播放所有动画 // 动画播放总控制器class animationSupper {funList {}//所有的动画//修改动画setAnimationAct(animationAct) {this.funList.map(item > {item.animationAct()})this.setAnimationAct animationActreturn this}//动画…

Excelize 开源基础库 2.8.1 版本发布, 2024 年首个更新

Excelize 是 Go 语言编写的用于操作 Office Excel 文档基础库&#xff0c;基于 ECMA-376&#xff0c;ISO/IEC 29500 国际标准。可以使用它来读取、写入由 Microsoft Excel™ 2007 及以上版本创建的电子表格文档。支持 XLAM / XLSM / XLSX / XLTM / XLTX 等多种文档格式&#xf…

一元函数微分学——刷题(21

目录 1.题目&#xff1a;2.解题思路和步骤&#xff1a;3.总结&#xff1a;小结&#xff1a; 1.题目&#xff1a; 2.解题思路和步骤&#xff1a; 出现式子&#xff1a; 就能说明&#xff1a; 接下来就是洛必达一下得到二次导的定义式&#xff1a; 3.总结&#xff1a; 出现式子…

输电线路微波覆冰监测装置助力电网应对新一轮寒潮

2月19日起&#xff0c;湖南迎来新一轮寒潮雨雪冰冻天气。为做好安全可靠的供电准备&#xff0c;国网国网湘潭供电公司迅速启动雨雪、覆冰预警应急响应&#xff0c;采取“人巡机巡可视化巡视”的方式&#xff0c;对输电线路实施三维立体巡检。该公司组织员工对1324套通道可视化装…

[AutoSar]BSW_Com03 DBC详解 (一)

目录 关键词平台说明一、DBC 定义1.1 相关工具 二、主要组成部分介绍2.1 Networks2.2 ECUs2.3 Network nodes2.4 messages2.5 signal2.6 Value Tables 三、主要组成部分关系图 关键词 嵌入式、C语言、autosar、OS、BSW 平台说明 项目ValueOSautosar OSautosar厂商vector &am…

自定义搭建管理系统

最近使用自己搭建的脚手架写了一个简易管理系统&#xff0c;使用webpackreactantd&#xff0c;搭建脚手架参考&#xff1a; 使用Webpack5搭建项目&#xff08;react篇&#xff09;_babel-preset-react-app-CSDN博客 搭建的思路&#xff1a; 1. 基建布局&#xff0c;使用antd的…

【Python】Windows本地映射远程Linux服务器上的端口(解决jupyter notebook无法启动问题)

创作日志&#xff1a; 学习深度学习不想在本地破电脑上再安装各种软件&#xff0c;我就用实验室的服务器配置环境&#xff0c;启动jupyter notebook时脑子又瓦特了&#xff0c;在自己Windows电脑上打开服务器提供的网址&#xff0c;那肯定打不开啊&#xff0c;以前在其它电脑上…