当前位置: 首页 > news >正文

设计模式 行为型 命令模式(Command Pattern)与 常见技术框架应用 解析

在这里插入图片描述

命令模式(Command Pattern)是一种行为型设计模式,它旨在将请求发送者和接收者解耦,通过将一个请求封装为一个对象,从而允许参数化客户端对象以进行不同的请求、排队请求或记录请求,并支持可撤销操作。

在软件开发中,经常会遇到需要将操作请求和操作的具体实现相分离的场景。比如在一个图形编辑软件里,用户可能执行绘制图形、移动图形、删除图形等多种操作。如果将这些操作的发起和具体执行逻辑紧密耦合在一起,会使代码的可维护性和扩展性变差。命令模式就是为了解决这类问题而诞生的,它把对操作的请求封装成独立的对象,使得我们可以像处理其他数据一样来处理这些操作请求。

一、核心思想

命令模式的核心在于将一个请求(命令)封装为一个对象。这样做的好处是可以将请求参数化,方便对请求进行存储、传递、调用、排队、记录日志以及支持撤销和重做等操作。通过这种方式,把发出命令的责任和执行命令的责任分割开,降低了系统模块之间的耦合度。

二、定义与结构

  1. 定义:将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。
  2. 结构
    • Command(命令):这是一个抽象类或接口,声明了执行操作的抽象方法execute()。
    • ConcreteCommand(具体命令):实现了Command接口,它知道具体的接收者对象,并在execute方法中调用接收者的相应操作方法。
    • Receiver(接收者):负责执行命令所要求的具体操作,它包含了真正实现业务逻辑的代码。
    • Invoker(调用者):负责调用命令对象执行请求,它持有一个命令对象的引用,通过调用命令对象的execute方法来触发操作。

三、角色

  1. 命令(Command):为所有具体命令类定义了统一的接口,使得调用者可以统一地调用命令的执行方法。
  2. 具体命令(ConcreteCommand):将一个接收者对象和一个动作绑定,在执行execute方法时,调用接收者的相应动作。
  3. 接收者(Receiver):知晓如何执行与请求相关的具体操作,是命令真正的执行者。
  4. 调用者(Invoker):负责安排命令的执行,它并不关心命令的具体实现,只关心如何触发命令的执行。

四、实现步骤及代码示例

  1. 定义命令接口
public interface Command {void execute();
}
  1. 定义接收者类
public class Light {public void on() {System.out.println("Light is on");}public void off() {System.out.println("Light is off");}
}
  1. 定义具体命令类
public class LightOnCommand implements Command {private Light light;public LightOnCommand(Light light) {this.light = light;}@Overridepublic void execute() {light.on();}
}public class LightOffCommand implements Command {private Light light;public LightOffCommand(Light light) {this.light = light;}@Overridepublic void execute() {light.off();}
}
  1. 定义调用者类
public class RemoteControl {private Command command;public RemoteControl(Command command) {this.command = command;}public void pressButton() {command.execute();}
}
  1. 测试代码
public class Main {public static void main(String[] args) {Light light = new Light();Command lightOnCommand = new LightOnCommand(light);Command lightOffCommand = new LightOffCommand(light);RemoteControl onRemote = new RemoteControl(lightOnCommand);RemoteControl offRemote = new RemoteControl(lightOffCommand);onRemote.pressButton();offRemote.pressButton();}
}

五、常见技术框架应用

JavaScript 实现命令模式:

// 接收者
function Door() {this.open = function () {console.log('Door is opened');};this.close = function () {console.log('Door is closed');};
}// 命令接口
function Command(door) {this.door = door;
}// 具体命令
function OpenDoorCommand(door) {Command.call(this, door);this.execute = function () {this.door.open();};
}function CloseDoorCommand(door) {Command.call(this, door);this.execute = function () {this.door.close();};
}// 调用者
function Remote(door) {this.command = null;this.setCommand = function (command) {this.command = command;};this.pressButton = function () {if (this.command) {this.command.execute();}};
}// 使用示例
let door = new Door();
let openCommand = new OpenDoorCommand(door);
let closeCommand = new CloseDoorCommand(door);let remote = new Remote(door);
remote.setCommand(openCommand);
remote.pressButton();remote.setCommand(closeCommand);
remote.pressButton();

六、应用场景

当你需要在不同的时刻指定、排列和执行请求的时候。
当你需要支持命令的撤销(Undo)功能时。
当你需要将请求作为对象进行传递和操作时。
当你需要组合多个操作形成宏命令时。
  1. 遥控器控制:如上面的示例所示,可以用命令模式实现遥控器来控制不同的家电设备,如电视、音响和灯。
  2. 文本编辑器操作:文本编辑器中的撤销、重做、剪切、复制、粘贴等操作可以使用命令模式来实现。
  3. 菜单系统:图形用户界面(GUI)应用中的菜单项和按钮操作可以通过命令模式来处理。
  4. 游戏中的动作:在游戏中,角色的动作和命令(如攻击、防御、跳跃等)可以使用命令模式来处理。
  5. 多级撤销操作:命令模式支持撤销和重做操作,因此在需要多级撤销的应用中很有用,如图像编辑器或CAD软件。
  6. 日程安排应用:在日程安排应用中,可以使用命令模式来处理添加、编辑、删除事件等操作。

七、优缺点

优点

  1. 解耦调用者和接收者:调用者和接收者之间通过命令对象进行交互,调用者无需了解接收者的具体实现细节,降低了模块之间的耦合度。
  2. 支持命令的扩展和组合:可以很方便地定义新的命令类,也可以将多个命令组合成一个复合命令,以实现更复杂的功能。
  3. 便于实现撤销和重做:通过在命令对象中保存操作的相关状态信息,可以很方便地实现操作的撤销和重做功能。

缺点

  1. 增加系统复杂度:由于引入了命令对象和相关的类,会增加系统的类和对象数量,导致系统复杂度上升,尤其是在命令种类繁多的情况下。
  2. 性能开销:命令的封装和传递会带来一定的性能开销,在对性能要求极高的场景下,需要谨慎评估是否适合使用命令模式。

在这里插入图片描述

相关文章:

设计模式 行为型 命令模式(Command Pattern)与 常见技术框架应用 解析

命令模式(Command Pattern)是一种行为型设计模式,它旨在将请求发送者和接收者解耦,通过将一个请求封装为一个对象,从而允许参数化客户端对象以进行不同的请求、排队请求或记录请求,并支持可撤销操作。 在软…...

【Redis】简介|优点|使用场景|为什么Redis快

目录 一、简介 二、特性(优点) 三、使用场景 一、简介 内存中存储数据的中间件,用于数据库,数据缓存,在分布式系统中能够大展拳脚 中间件:应用程序可以直接从 Redis 中获取数据,而不必频繁地…...

Clisoft SOS与CAD系统集成

Clisoft SOS与CAD系统集成 以下内容大部分来自官方文档,目前只用到与Cadence Virtuoso集成,其他还未用到,如有问题或相关建议,可以留言。 与Keysight ADS集成 更新SOS客户端配置文件sos.cfg,以包含支持ADS的模板&am…...

【linux系统之redis6】redis的安装与初始化

下载redis的linux对应的安装包,并上传到linux虚拟机里面 解压压缩包 tar -zxzf redis-6.2.6.tar.gz解压后,进入redis文件 cd redis-6.2.6执行编译 make && make install看到下图,就说明redis安装成功了 默认的安装路径&#xff0c…...

Backend - EF Core(C# 操作数据库 DB)

目录 一、EF Core 1. 使用的ORM框架(对象关系映射) 2. EFCore 常见两种模式 3. EFCore 提供程序 二、 EF 操作数据库(Code First) 1. 下载NuGet插件 2.创建模型类文件 3.创建DBContext文件 4.Programs.cs文件 5.appsettings.Devel…...

WebSocket 性能优化:从理论到实践

在前四篇文章中,我们深入探讨了 WebSocket 的基础原理、服务端开发、客户端实现和安全实践。今天,让我们把重点放在性能优化上,看看如何构建一个高性能的 WebSocket 应用。我曾在一个直播平台项目中,通过一系列优化措施,将单台服务器的并发连接数从 1 万提升到 10 万。 性能挑…...

我用AI学Android Jetpack Compose之入门篇(2)

我跑成功了第一个Compose应用,但我还是有很多疑问,请人工智能来解释一下吧。答案来自 通义千问 文章目录 1.请解释一下Compose项目的目录结构。根目录模块目录(通常是app)app/build.gradleapp/src/mainapp/src/main/uiapp/src/ma…...

以太网协议在汽车应用中的动与静

为了让网络中的设备能够随时或随地接入网络或离开网络,做到:接入时无需多余的配置就能和其他设备互相通信;离开时又不会导致设备或网络崩溃。以太网从物理层到协议层展现出多方面的灵活性,,使其成为连接各种设备和系统…...

【C语言】_指针与数组

目录 1. 数组名的含义 1.1 数组名与数组首元素的地址的联系 1.3 数组名与首元素地址相异的情况 2. 使用指针访问数组 3. 一维数组传参的本质 3.1 代码示例1:函数体内计算sz(sz不作实参传递) 3.2 代码示例2:sz作为实参传递 3…...

Selenium 的四种等待方式及使用场景

Selenium 的四种等待方式及使用场景 隐式等待(Implicit Wait)显式等待(Explicit Wait)自定义等待(Custom Wait)固定等待(Sleep) 1. 隐式等待 定义: 隐式等待是为 WebD…...

React知识盲点——组件通信、性能优化、高级功能详解(大纲)

组件通信 React 组件通信详解 在 React 中,组件通信是一个核心概念,主要指的是如何让不同的组件共享和传递数据。React 提供了多种机制来实现组件间的数据传递和状态共享。以下是几种常见的组件通信方式,包括:父子组件通信&…...

Vue 按键生成多个表单

本文通过 vueele&#xff0c;通过循环ref的方法生成多个表单,代码如下&#xff1a; <template><div><el-button click"addText" style"margin: 15px 0; ">添加字段</el-button><div v-for"item, index in dataList"…...

网络安全:交换机技术

单播&#xff0c;组播广播 单播(unicast): 是指封包在计算机网络的传输中&#xff0c;目的地址为单一目标的一种传输方式。它是现今网络应用最为广泛&#xff0c;通常所使用的网络协议或服务大多采用单播传输&#xff0c;例如一切基于TCP的协议。组播(multicast): 也叫多播&am…...

Flask 快速入门

1. Flask 简介 1.1 什么是 Flask Flask 是一个用 Python 编写的轻量级 Web 框架&#xff0c;被誉为 微框架。它提供基础功能&#xff0c;如路由、请求处理和模板引擎&#xff0c;但不强迫开发者使用特定库或工具&#xff0c;赋予开发人员高度的自由选择权&#xff0c;以满足不…...

C#设计模式(行为型模式):备忘录模式,时光倒流的魔法

C#设计模式&#xff1a;备忘录模式&#xff0c;时光倒流的魔法 在软件开发中&#xff0c;我们经常会遇到需要保存对象状态&#xff0c;并在未来某个时刻恢复的场景。例如&#xff1a; 撤销操作&#xff1a; 文本编辑器中的撤销功能&#xff0c;游戏中的回退操作。事务回滚&am…...

数据库高安全—角色权限:权限管理权限检查

目录 3.3 权限管理 3.4 权限检查 书接上文数据库高安全—角色权限&#xff1a;角色创建角色管理&#xff0c;从角色创建和角色管理两方面对高斯数据库的角色权限进行了介绍&#xff0c;本篇将从权限管理和权限检查方面继续解读高斯数据库的角色权限。 3.3 权限管理 &#x…...

FastAPI 的依赖注入与生命周期管理深度解析

FastAPI 的依赖注入与生命周期管理深度解析 目录 &#x1f527; 依赖注入与 FastAPI 高级特性 1.1 依赖注入的基础与核心概念1.2 FastAPI 的依赖注入机制与设计理念1.3 FastAPI 依赖注入的异步特性 &#x1f579; 生命周期与依赖的异步管理 2.1 依赖的生命周期管理&#xff1…...

【express-generator】05-路由中间件和错误处理(第一阶段收尾)

一、前言 上篇文章我们介绍了express-generator的请求体解析&#xff0c;重点讲了常用的请求体数据格式&#xff08;JSON/URL 编码的表单数据&#xff09;以及一个FILE文件上传&#xff0c;同时搭配代码示范进行辅助理解。 二、本篇重点 我们继续第一阶段的知识&#xff0c;…...

Linux环境下确认并操作 Git 仓库

在软件开发和版本控制中&#xff0c;Git 已成为不可或缺的工具。有时&#xff0c;我们需要确认某个目录是否是一个 Git 仓库&#xff0c;并在该目录中运行脚本。本文将详细介绍如何确认 /usr/local/src/zcxt/backend/policy-system-backend 目录是否是一个 Git 仓库&#xff0c…...

UDP -- 简易聊天室

目录 gitee&#xff08;内有详细代码&#xff09; 图解 MessageRoute.hpp UdpClient.hpp UdpServer.hpp Main.hpp 运行结果&#xff08;本地通信&#xff09; 如何分开对话显示&#xff1f; gitee&#xff08;内有详细代码&#xff09; chat_room zihuixie/Linux_Lear…...

Dial2硬件传感器适配库:嵌入式固件的契约实现层

1. 项目概述 Dial2HardwareSensors 是一个面向 AhmsVille Dial 2 硬件平台的专用传感器适配层实现库。该库不提供抽象接口定义&#xff0c;而是聚焦于在真实嵌入式硬件上完成传感器驱动的最终落地——即把 AhmsVille Dial2 sensor adapter interfaces &#xff08;通常为纯虚…...

YOLOv8智慧园区应用:多目标协同检测部署

YOLOv8智慧园区应用&#xff1a;多目标协同检测部署 1. 项目概述 在现代智慧园区管理中&#xff0c;如何快速准确地识别和统计园区内的各类物体是一个关键挑战。传统的人工巡查方式效率低下&#xff0c;而基于深度学习的多目标检测技术为这一问题提供了智能化的解决方案。 本…...

LaserGRBL:5分钟掌握专业激光雕刻软件的核心技巧

LaserGRBL&#xff1a;5分钟掌握专业激光雕刻软件的核心技巧 【免费下载链接】LaserGRBL Laser optimized GUI for GRBL 项目地址: https://gitcode.com/gh_mirrors/la/LaserGRBL LaserGRBL是一款专为激光雕刻机设计的Windows图形界面软件&#xff0c;它基于开源的GRBL控…...

【AI智能体实战】Dify与MCP服务深度集成:从零构建企业级智能问答系统

1. 为什么选择DifyMCP搭建企业级问答系统 最近两年&#xff0c;企业知识库智能化改造的需求呈现爆发式增长。我经手过的十几个项目中&#xff0c;客户普遍反映传统问答系统存在三个痛点&#xff1a;第一是模型效果不稳定&#xff0c;简单问题能回答但复杂业务逻辑就出错&#x…...

自动化脚本ui开发基础入门

自动化脚本ui采用XML 描述界面 JS 处理逻辑的模式&#xff0c;零基础也能快速上手自定义可视化界面&#xff0c;本文结合官方文档&#xff0c;从核心概念、开发规则、基础控件、全局函数到完整 Demo&#xff0c;全面讲解冰狐 UI 开发入门知识&#xff0c;助力开发者快速搭建实…...

InnoDB存储结构全解析:行页区段与单表W行的关系既

一、背景与问题缘起 MySQL 5.6.51 版本下 2000 万行核心业务表开展新增字段操作&#xff0c;需求为新增BIGINT(19) NOT NULL DEFAULT 0 COMMENT 注释&#xff08;因业务实际需要存储大数值关联字段&#xff09;。 表的核心特性为Java 多线程密集读写&#xff0c;业务请求持续高…...

告别会议记录焦虑:TMSpeech 如何用离线语音识别重塑你的工作效率

告别会议记录焦虑&#xff1a;TMSpeech 如何用离线语音识别重塑你的工作效率 【免费下载链接】TMSpeech 腾讯会议摸鱼工具 项目地址: https://gitcode.com/gh_mirrors/tm/TMSpeech 你是否曾在重要会议中因为分心记录而错过关键讨论&#xff1f;是否担心云端语音识别服务…...

PS4手柄Windows完全指南:用DS4Windows解锁专业级游戏体验

PS4手柄Windows完全指南&#xff1a;用DS4Windows解锁专业级游戏体验 【免费下载链接】DS4Windows Like those other ds4tools, but sexier 项目地址: https://gitcode.com/gh_mirrors/ds/DS4Windows 想在Windows电脑上完美使用PS4手柄吗&#xff1f;DS4Windows为你提供…...

突破付费墙限制:从技术原理到个性化解决方案的完整指南

突破付费墙限制&#xff1a;从技术原理到个性化解决方案的完整指南 当你在研究某个专业领域的前沿动态时&#xff0c;是否曾因遇到"订阅后阅读全文"的提示而被迫中断探索&#xff1f;在信息获取成本日益增加的今天&#xff0c;如何合法合规地突破内容访问限制&#x…...

别再轮询了!STM32 ADC多通道采集,用DMA+定时器实现后台自动搬运数据(附CubeMX配置)

STM32 ADC多通道采集&#xff1a;DMA定时器实现零CPU占用的数据搬运方案 在工业传感器监测或物联网设备开发中&#xff0c;ADC多通道采集是基础但关键的技术环节。传统轮询方式不仅占用大量CPU资源&#xff0c;还会因处理延迟导致数据丢失。本文将分享一种基于DMA和定时器触发的…...