十七、行为型(命令模式)

news/2024/10/25 7:12:29/

命令模式(Command Pattern)

概念
命令模式是一种行为型设计模式,它将请求封装成一个对象,从而使您可以使用不同的请求对客户进行参数化,排队请求,以及支持可撤销操作。通过这种模式,调用操作的对象和实际执行操作的对象解耦,使得系统更加灵活。


应用场景

  1. 请求参数化:在某些情况下,您可能需要将请求参数化并传递给多个调用者。命令模式允许将请求封装为对象,便于传递和存储。

  2. 队列和日志:可以将请求存储在队列中,稍后处理。这在异步执行或日志记录系统中非常有用。

  3. 撤销操作:命令对象可以保存请求执行前的状态,从而支持撤销和重做操作。

  4. 宏命令:当需要执行一系列操作时,可以将它们封装成一个宏命令,以便一次性执行。


注意点

  1. 命令对象数量:如果系统中存在大量不同请求,命令对象的数量会显著增加,从而增加系统复杂性。

  2. 状态管理:需要确保命令对象能够保存执行前后的状态,以便实现撤销功能。

  3. 过于复杂的命令:如果命令执行逻辑非常复杂,可能会导致命令对象的实现变得难以维护。


核心要素

  1. Command(命令接口):定义命令的接口,通常包含 execute()undo() 方法。

  2. ConcreteCommand(具体命令):实现命令接口的类,负责调用接收者的相应方法来执行操作。

  3. Receiver(接收者):实际执行命令请求的对象。

  4. Invoker(调用者):负责调用命令对象的 execute() 方法来执行命令。

  5. Client(客户端):创建具体命令对象并将接收者与命令对象关联。


Java代码完整示例

示例:简单的命令模式实现

// 命令接口
interface Command {void execute();void undo(); // 撤销方法
}// 接收者类
class Light {public void turnOn() {System.out.println("The light is on.");}public void turnOff() {System.out.println("The light is off.");}
}// 具体命令类:打开灯
class TurnOnLightCommand implements Command {private Light light;public TurnOnLightCommand(Light light) {this.light = light;}@Overridepublic void execute() {light.turnOn();}@Overridepublic void undo() {light.turnOff();}
}// 具体命令类:关闭灯
class TurnOffLightCommand implements Command {private Light light;public TurnOffLightCommand(Light light) {this.light = light;}@Overridepublic void execute() {light.turnOff();}@Overridepublic void undo() {light.turnOn();}
}// 调用者类
class RemoteControl {private Command command;private Command lastCommand; // 记录上一个命令public void setCommand(Command command) {this.command = command;}public void pressButton() {command.execute();lastCommand = command; // 记录当前命令}public void pressUndo() {if (lastCommand != null) {lastCommand.undo(); // 撤销上一个命令}}
}// 客户端代码
public class CommandPatternDemo {public static void main(String[] args) {Light livingRoomLight = new Light();// 创建命令对象Command turnOn = new TurnOnLightCommand(livingRoomLight);Command turnOff = new TurnOffLightCommand(livingRoomLight);// 设置命令到调用者RemoteControl remote = new RemoteControl();// 打开灯remote.setCommand(turnOn);remote.pressButton();// 撤销:关闭灯remote.pressUndo();// 关闭灯remote.setCommand(turnOff);remote.pressButton();// 撤销:打开灯remote.pressUndo();}
}

输出结果

The light is on.
The light is off.
The light is off.
The light is on.

各种变形用法完整示例

  1. 支持撤销操作的命令模式

    通过在命令接口中添加 undo() 方法,您可以轻松支持命令的撤销功能。

    代码示例:支持撤销的命令模式

    // 上面的代码示例已包含撤销功能,您可以直接使用。
    
  2. 命令模式

    宏命令允许将多个命令打包为一个命令对象,以便一次性执行。

    代码示例:宏命令

    import java.util.ArrayList;
    import java.util.List;// 宏命令类
    class MacroCommand implements Command {private List<Command> commands = new ArrayList<>();public void addCommand(Command command) {commands.add(command);}@Overridepublic void execute() {for (Command command : commands) {command.execute();}}@Overridepublic void undo() {for (Command command : commands) {command.undo();}}
    }public class MacroCommandDemo {public static void main(String[] args) {Light livingRoomLight = new Light();Command turnOn = new TurnOnLightCommand(livingRoomLight);Command turnOff = new TurnOffLightCommand(livingRoomLight);MacroCommand macroCommand = new MacroCommand();macroCommand.addCommand(turnOn);macroCommand.addCommand(turnOff);// 执行宏命令RemoteControl remote = new RemoteControl();remote.setCommand(macroCommand);remote.pressButton(); // 执行所有命令}
    }
    
  3. 命令队列

    在异步执行或延迟执行场景中,可以将命令存储在队列中。

    代码示例:命令队列

    import java.util.LinkedList;
    import java.util.Queue;class CommandQueue {private Queue<Command> commandQueue = new LinkedList<>();public void addCommand(Command command) {commandQueue.offer(command);}public void executeAll() {while (!commandQueue.isEmpty()) {Command command = commandQueue.poll();command.execute();}}
    }public class CommandQueueDemo {public static void main(String[] args) {CommandQueue commandQueue = new CommandQueue();Light livingRoomLight = new Light();commandQueue.addCommand(new TurnOnLightCommand(livingRoomLight));commandQueue.addCommand(new TurnOffLightCommand(livingRoomLight));// 执行命令队列中的所有命令commandQueue.executeAll();}
    }
    

通过这些示例,命令模式的灵活性和强大功能得以体现,可以根据具体需求实现多种变形用法。


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

相关文章

3.1.1 ReactOS系统中二叉树创建一个MEMORY_AREA节点

二叉树中创建一个MEMORY_AREA节点&#xff1a; 二叉树中创建一个MEMORY_AREA节点&#xff1a; MmCreateMemoryArea() 参数AddressSpace是MADDRESS SPACE结构指针&#xff0c;所指向的数据结构代表着一个进程的用 户空间。 参数BaseAddress是个指针&#xff0c;用来给定和返回内…

【Android】使用 Compose 自定义 View 实现从 0 ~ 1 仿 EChat 柱状图

目录 前言DrawScopeDrawScope Api 绘制柱状图绘制 X 轴绘制 Y 轴绘制柱状背景绘制柱状前景完整代码最终效果 存在的问题 前言 本文讲的是使用 compose 去自定义 View &#xff0c;如果您未曾通过继承 View 的方式去实现自定义 View&#xff0c;那么&#xff0c;我建议在观看本…

3D虚拟服装试穿技术:迈向元宇宙与AR电商的新时代

随着电子商务的不断进化,消费者对于在线购物体验的需求也在不断提升。在这样的背景下,3D虚拟服装试穿技术正逐渐成为连接现实世界与数字世界的桥梁,为用户带来前所未有的沉浸式购物体验。本文将介绍一种创新的3D虚拟服装试穿系统——GS-VTON,它旨在克服现有技术局限,并提供…

ECharts饼图-富文本标签,附视频讲解与代码下载

引言&#xff1a; 在数据可视化的世界里&#xff0c;ECharts凭借其丰富的图表类型和强大的配置能力&#xff0c;成为了众多开发者的首选。今天&#xff0c;我将带大家一起实现一个饼图图表&#xff0c;通过该图表我们可以直观地展示和分析数据。此外&#xff0c;我还将提供详…

【Mac 上将 MOV 格式转换为 MP4 格式的简易指南】

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

无人机之室内定位技术篇

无人机的室内定位技术是实现无人机在室内环境中精准导航和定位的关键技术。由于室内环境复杂&#xff0c;卫星导航系统&#xff08;如GPS&#xff09;无法提供有效的信号&#xff0c;因此需要依赖其他室内定位技术。 一、主要技术类型 基于视觉的定位技术 原理&#xff1a;利…

智联招聘×Milvus:向量召回技术提升招聘匹配效率

01. 业务背景 在智联招聘平台&#xff0c;求职者和招聘者之间的高效匹配至关重要。招聘者可以发布职位寻找合适的人才&#xff0c;求职者则通过上传简历寻找合适的工作。在这种复杂的场景中&#xff0c;我们的核心目标是为双方提供精准的匹配结果。在搜索推荐场景下&#xff0c…

客户端与服务端通信的端口以及新增ARP缓存

客户端&#xff08;例如浏览器&#xff09;在与服务器通信时确实会使用一个随机的、高于1024的端口。不过&#xff0c;在端口转发的场景中&#xff0c;我们主要关注的是两个不同的层面&#xff1a;服务器的监听端口&#xff08;即最终目的地的端口&#xff09;和客户端的源端口…