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

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

日常叨逼叨

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://xiahunao.cn/news/2799770.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

实战打靶集锦-025-HackInOS

文章目录 1. 主机发现2. 端口扫描3. 服务枚举4. 服务探查5. 提权5.1 枚举系统信息5.2 探索一下passwd5.3 枚举可执行文件5.4 查看capabilities位5.5 目录探索5.6 枚举定时任务5.7 Linpeas提权 靶机地址&#xff1a;https://download.vulnhub.com/hackinos/HackInOS.ova 1. 主机…

万界星空科技MES系统,实现数字化智能工厂

万界星空科技帮助制造型企业解决生产过程中遇到的生产过程不透明&#xff0c;防错成本高&#xff0c;追溯困难&#xff0c;品质不可控&#xff0c;人工效率低下&#xff0c;库存积压&#xff0c;交期延误等问题&#xff0c;从而达到“降本增效”的目标。打通各个信息孤岛&#…

Android进阶(二十九) 走近 IntentFilter

文章目录 一、什么是IntentFilter &#xff1f;二、IntentFilter 如何过滤隐式意图&#xff1f;2.1 动作测试2.2 类别测试2.3 数据测试 一、什么是IntentFilter &#xff1f; 如果一个 Intent 请求在一片数据上执行一个动作&#xff0c; Android 如何知道哪个应用程序&#xf…

力扣 面试题 05.06. 整数转换

思路&#xff1a; 牵扯到二进制数&#xff0c;基本上要考虑位运算符&#xff0c;相关知识可以见http://t.csdnimg.cn/fzts7 之前做过类似的题目&#xff0c;大致思路就是先用按位异或^找出不同位&#xff0c;再用n&&#xff08;n-1&#xff09;计算出不同位的个数&#x…

恒峰—高压森林应急消防泵:保障森林安全

在自然环境中&#xff0c;森林起着至关重要的作用&#xff0c;它们不仅为我们提供木材和清新的空气&#xff0c;还是众多生物的家园。然而&#xff0c;随着人类活动的增长&#xff0c;森林面临着越来越严重的火灾威胁。为了保护这些宝贵的资源&#xff0c;我们需要一种高效、可…

10.CSS3的calc函数

CSS3 的 calc 函数 经典真题 CSS 的计算属性知道吗&#xff1f; CSS3 中的 calc 函数 calc 是英文单词 calculate&#xff08;计算&#xff09;的缩写&#xff0c;是 CSS3 的一个新增的功能。 MDN 的解释为可以用在任何长度、数值、时间、角度、频率等处&#xff0c;语法如…

为全志D1开发板移植LVGL日历控件和显示天气

利用TCP封装HTTP包请求天气信息 Linux还真是逐步熟悉中&#xff0c;现在才了解到Linux即没有原生的GUI&#xff0c;也没有应用层协议栈&#xff0c;所以要实现HTTP应用&#xff0c;必须利用TCP然后自己封装HTTP数据包。本篇即记录封装HTTP数据包&#xff0c;到心知天气请求天气…

【Linux】再谈进程地址空间

目录 一、引入 二、物理内存和外设空间的交互 三、解决页表过大问题 一、引入 我们在往期的博客中有讲解过进程地址空间&#xff1a;【Linux】进程地址空间 但是在上述博客中我们只是对进程地址空间的左边部分详细进行了讲解&#xff0c;下面我们就来谈谈右边的部分&#…

git版本回退在eclipse和命令中的操作

一.背景 老程序员了&#xff0c;熟悉eclipsesvn&#xff0c;git用的不溜。近几年用了git&#xff0c;偶尔修改了某个文件希望放弃本次修改重新恢复到最新版本重新修改。或者回退到某个版本&#xff0c;再修改。记录一下Eclipse中的操作&#xff0c;和命令操作的情况。 二.Ecli…

操作系统导论-课后作业-ch19

1. 本书在第6章中有过介绍&#xff0c;gettimeofday函数最多精确到us&#xff0c;并且大致精确&#xff08;并不完全精确&#xff09;&#xff0c;需要多迭代几次减少误差&#xff0c;循环次数太多也会导致结束时间小于开始时间&#xff08;即回滚&#xff09;的现象&#xff…

每日shell脚本之超级整合程序3.0

每日shell脚本之超级整合程序3.0 本期带来之前的升级版2.0整合脚本程序,学习工作小利器,同时模块化构建方便二次开发。 上图 上源码 #!/usr/bin/bash # *******************************************# # * CDDN : M乔木 # # * qq邮箱 …

社区分享|中华保险基于MeterSphere开展接口自动化测试

中华联合保险集团股份有限公司&#xff08;以下简称为“中华保险”&#xff09;始创于1986年&#xff0c;是全国唯一一家以“中华”冠名的国有控股保险公司。截至2022年12月底&#xff0c;中华保险总资产为1006.06亿元&#xff0c;在全国拥有超过2900个营业网点&#xff0c;员工…

06 分频器设计

分频器简介 实现分频一般有两种方法&#xff0c;一种方法是直接使用 PLL 进行分频&#xff0c;比如在 FPGA 或者 ASIC 设计中&#xff0c;都可以直接使用 PLL 进行分频。但是这种分频有时候受限于 PLL 本身的特性&#xff0c;无法得到频率很低的时钟信号&#xff0c;比如输入 …

Windows安装PHP及在VScode中配置插件,使用PHP输出HelloWorld

安装PHP PHP官网下载地址(8.3版本)&#xff1a;PHP For Windows&#xff1a;二进制文件和源代码发布 点击下载.zip格式压缩包&#xff1a; 历史版本在Old archives中下载。推荐在Documentation download中下载官方文档&#xff0c;方便学习。 下载完成后在一个顺眼的地方解压压…

Point.java

Point.java 让我们来找茬&#xff0c;(⊙o⊙)看看哪里不一样咯&#xff01;&#xff01;&#xff01; package algorithm_graphics_2;/** Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject t…

Zabbix 6.2.1 安装

目录 1、监控介绍 监控的重要性 网站的可用性 监控范畴 如何监控 2、Zabbix 介绍 zabbix 简介 zabbix 主要功能 zabbix 监控范畴 Zabbix 监控组件 zabbix 常见进程 zabbix agentd 工作模式 zabbix 环境监控中概念 3、搭建LNMP 拓扑规划 安装MySQL 安装 Nginx …

【视频编解码】M-JPEG压缩、H.264压缩 对比

简介 参考这篇文章&#xff1a;https://blog.csdn.net/qq_41248872/article/details/83590337 写的比较好&#xff0c;这里就不赘述了。 我们在视频传输的时候&#xff0c;需要压缩&#xff0c;常见的压缩包括: jpeg 压缩h264 压缩 当然使用最多的还是 264, 毕竟他的压缩比…

【Flink经济】Flink 内存管理

面临的问题 目前&#xff0c; 大数据计算引擎主要用 Java 或是基于 JVM 的编程语言实现的&#xff0c;例如 Apache Hadoop、 Apache Spark、 Apache Drill、 Apache Flink 等。 Java 语言的好处在于程序员不需要太关注底层内存资源的管理&#xff0c;但同样会面临一个问题&…

【快速搞定Webpack5】修改输出文件目录及自动清理上次打包文件(五)

介绍 默认情况下webpack打包后&#xff0c;我们的图片和js等文件都会被打包到dist目录下&#xff0c;文件多了混淆在一起一方面不利于文件的查找和管理&#xff0c;另外一方面看上去也不美观。 所以今天我们学习的内容就是控制输出后的文件进入不同的目录。 一、配置 新增4…

小米标准模组+MCU 快速上手开发(二)——之模组串口调试

小米标准模组MCU 开发笔记之固件调试 背景技术名词简介● 小米IoT开发者平台● 小米IoT 模组● 固件● OTA● CRC32 固件双串口调试● MHCWB6S-IB 模组资料下载● MHCWB6S-IB 模组管脚图● 上电调试 背景 小米标准模组MCU的开发过程中&#xff0c;由于部分官方资料较为古早&am…