开关不一定是开关灯用 - 命令模式(Command Pattern)

news/2025/1/10 15:26:59/

命令模式(Command Pattern)

命令模式(Command Pattern)

命令模式(Command Pattern)是一种行为型设计模式,它将请求封装为对象,从而使你可以用不同的请求对客户进行参数化、队列或者日志请求,以及支持可撤销的操作。命令模式的核心思想是将“请求”作为一个对象来处理,将发出请求的责任和执行请求的责任分割开。

太抽象了,我们还是举个现实中的例子
假如你现在在装修家,你很有可能要买一个开关。但是我们这个开关不一定是用来开关灯的,也有可能是用来控制别的东西,所以这个开关不一定是跟灯是关联的。我们的开关你可以当成我们面向对象设计里面的一个对象,它不跟灯有直接的耦合关系。开关相当于发送者,开关与什么用电器关联,开关就控制哪一个用电器。实际上你可以这样理解命令模式,通过使用命令模式,我们隔离发送请求的与执行请求的对象。

命令设计模式

命令设计模式结构图

在这里插入图片描述

命令设计模式涉及的角色

  1. 命令接口(Command):声明了所有具体命令必须实现的方法
java">public interface Command {void execute();void undo(); // 可选,用于撤销操作
}
  1. 具体命令(ConcreteCommand):实现了Command接口的具体类。每个具体命令都包含对一个接收者的引用,并负责调用接收者的方法来执行实际的操作。
java">public class ConcreteCommand implements Command {private final Receiver receiver;public ConcreteCommand(Receiver receiver) {this.receiver = receiver;}@Overridepublic void execute() {receiver.performAction();}@Overridepublic void undo() {receiver.undoAction(); // 假设接收者有撤销功能}
}
  1. 接收者(Receiver):接收者知道如何执行与请求相关的操作。任何类都可以成为接收者,只要它提供了可以被命令对象调用的方法。
java">public class Receiver {public void performAction() {System.out.println("Executing action in Receiver");}public void undoAction() {System.out.println("Undoing action in Receiver");}
}
  1. 请求发送者(Invoker):请求发送者持有一个命令对象,并负责调用命令对象的execute()方法来触发请求。发送者不需要知道具体的接收者是谁,也不需要知道请求的具体内容。
java">public class Invoker {private Command command;public void setCommand(Command command) {this.command = command;}public void executeCommand() {if (command != null) {command.execute();}}public void undoCommand() {if (command != null) {command.undo();}}
}
  1. 客户端(Client):客户端创建具体的命令对象,并将其与接收者关联起来。然后,客户端将命令对象传递给请求发送者,由发送者在适当的时候调用命令对象的execute()方法。
java">public class Client {public static void main(String[] args) {Receiver receiver = new Receiver();Command command = new ConcreteCommand(receiver);Invoker invoker = new Invoker();invoker.setCommand(command);invoker.executeCommand(); // 执行命令invoker.undoCommand(); // 撤销命令}
}

talk is cheap, show you my code

我们还是把我们举得例子转化成代码:

  1. 定义接收者(Receiver):首先,我们定义Light类,它包含打开和关闭灯光的方法。
java">public class Light {public void on() {System.out.println("The light is ON.");}public void off() {System.out.println("The light is OFF.");}
}
  1. 定义命令接口(Command Interface):接下来,我们定义一个命令接口Command,所有具体命令都必须实现这个接口。
java">public interface Command {void execute();
}
  1. 实现具体命令(Concrete Commands)
java">public class LightOnCommand implements Command {private final Light light;public LightOnCommand(Light light) {this.light = light;}@Overridepublic void execute() {light.on();}
}public class LightOffCommand implements Command {private final Light light;public LightOffCommand(Light light) {this.light = light;}@Overridepublic void execute() {light.off();}
}
  1. 定义请求发送者(Invoker)
    现在,我们创建一个Switch类作为请求发送者。它持有一个命令对象,并负责调用命令对象的execute()方法。
java">public class Switch {private Command command;public void setCommand(Command command) {this.command = command;}public void press() {if (command != null) {command.execute();} else {System.out.println("No command set.");}}
}
  1. 客户端代码(Client)
java">public class Client {public static void main(String[] args) {// 创建接收者Light light = new Light();// 创建命令对象Command lightOn = new LightOnCommand(light);Command lightOff = new LightOffCommand(light);// 创建请求发送者并设置命令Switch switchButton = new Switch();switchButton.setCommand(lightOn);switchButton.press(); // 执行打开灯光命令switchButton.setCommand(lightOff);switchButton.press(); // 执行关闭灯光命令}
}

最后,在客户端代码中,我们将创建一个Light实例,以及相应的LightOnCommand和LightOffCommand实例。然后,我们将这些命令设置到Switch对象中,并通过调用press()方法来触发命令的执行。

总结

命令模式的主要优点包括:

  1. 降低了系统的耦合度。
  2. 新的命令可以很容易地加入到系统中。
  3. 可以方便地实现对请求的撤销和重做。
    不过,命令模式也可能增加系统的复杂性,因为它需要引入许多新的类。如果系统比较简单,使用命令模式可能会显得过于繁琐。

http://www.ppmy.cn/news/1562007.html

相关文章

maven下载依赖报错:on-resolvable parent POM xxx

maven 构建项目时报错 Non-resolvable parent POM for com.itheima:integation-mybatis:0.0.1-SNAPSHOT: org.springframework.boot:spring-boot-starter-parent:pom:2.5.3 failed to transfer from http://maven.aliyun.com/nexus/content/groups/public/ during a previous a…

[备忘.OFD]OFD是什么、OFD与PDF格式文件的互转换

‌OFD(Open Fixed-layout Document)是一种由工业和信息化部软件司牵头中国电子技术标准化研究院制定的版式文档国家标准,属于中国的一种自主格式‌‌。OFD旨在打破政府部门和党委机关电子公文格式不统一的问题,以方便电子文档的存…

AIDD-人工智能药物设计-通过组合生物合成产生新的类似物的抗真菌费尔南型三萜多聚类素的生物合成表征

Org. Biomol. Chem.|通过组合生物合成产生新的类似物的抗真菌费尔南型三萜多聚类素的生物合成表征 今天为大家介绍的是来自Xin-Yu Li、Jian-Ming Lv和Zhi-Qin Cao团队的一篇论文。费尔南型三萜是植物和真菌中的一类具有广泛生物活性的天然产物,其中真菌来源的Polyt…

深度学习与计算机视觉 (博士)

文章目录 零、计算机视觉概述一、深度学习相关概念1.学习率η2.batchsize和epoch3.端到端(End-to-End)、序列到序列(Seq-to-Seq)4.消融实验5.学习方式6.监督学习的方式(1)有监督学习(2)强监督学习(3)弱监督学习(4)半监督学习(5)自监督学习(6)无监督学习(7)总结:不同…

运动相机拍摄的视频打不开怎么办

3-10 GoPro和大疆DJI运动相机的特点,小巧、高清、续航长、拍摄稳定,很多人会在一些重要场合用来拍摄视频,比如可以用来拿在手里拍摄快速运动中的人等等。 但是毕竟是电子产品,有时候是会出点问题的,比如意外断电、摔重…

AF3 tensor_tree_map函数解读

AlphaFold3 递归函数 dict_map 和 tree_map,用于对嵌套的数据结构(如字典、列表、元组等)中的每个“叶子节点”应用指定的操作。最后,通过 partial 函数创建了 tensor_tree_map,专门用于对包含 torch.Tensor 的树形结构…

使用 Flask 和 PaddleOCR 的车牌识别项目安装与打包教程

文章目录 一、环境安装1. 安装 Python2. 创建虚拟环境3. 安装依赖 二、项目实现代码文件 app.py 三、打包流程1. 安装 pyinstaller2. 生成可执行文件3. 验证可执行文件 四、测试车牌识别服务1. 使用 Postman 或 curl 测试2. 校验车牌 五、提供给运维的打包文件 本教程基于 Flas…

边缘计算应用十大领域

边缘计算解决了互联网的网速问题,作为实现边缘计算的基础,那边缘计算是5G与产业互联网、物联网时代的重要技术支撑,也正迎来广阔的增长空间。那么现在我们生活中有哪些领域正在使用边缘计算呢?今天我们来盘点一下我们身边正在使用…