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

【前端设计模式】之命令模式

引言

命令设计模式是一种行为型设计模式,它允许你将命令封装到一个对象中,从而使你可以参数化不同的请求,以及存储、排队、重播和撤销请求。这种设计模式在处理用户界面操作、远程网络请求或其他需要异步执行的操作时非常有用。在前端开发中,我们经常需要处理复杂的操作和交互逻辑。命令模式允许我们将操作封装成对象,并将其作为参数传递、存储或记录,从而实现优雅地管理和执行操作。

命令模式的特性

命令模式具有以下特性:

  1. 命令(Command):封装了一个具体操作及其参数,并提供了执行该操作的方法。
  2. 接收者(Receiver):负责执行具体操作的对象。
  3. 调用者(Invoker):负责调用命令对象并触发其执行方法。
  4. 客户端(Client):创建并配置具体命令对象,并将其传递给调用者进行执行。
  5. 撤销与重做:通过记录历史命令对象,可以实现撤销和重做操作。

应用示例

在前端开发中,我们可以使用命令模式来解决以下问题,并提供相应的代码示例:

1. 按钮点击事件

在处理按钮点击事件时,命令模式可以帮助我们将具体操作封装成命令对象,并将其与按钮关联起来。

 
// 定义命令接口
class Command {execute() {throw new Error("execute() method must be implemented");}
}
// 定义具体命令类
class SaveCommand extends Command {constructor(receiver) {super();this.receiver = receiver;}execute() {this.receiver.save();}
}
class DeleteCommand extends Command {constructor(receiver) {super();this.receiver = receiver;}execute() {this.receiver.delete();}
}
// 定义接收者类
class Receiver {save() {console.log("Saving data...");// 执行保存操作的逻辑}delete() {console.log("Deleting data...");// 执行删除操作的逻辑}
}
// 定义调用者类
class Invoker {setCommand(command) {this.command = command;}executeCommand() {this.command.execute();}
}
// 使用示例
const receiver = new Receiver();
const saveCommand = new SaveCommand(receiver);
const deleteCommand = new DeleteCommand(receiver);
const invoker = new Invoker();
invoker.setCommand(saveCommand);
invoker.executeCommand(); // 输出: "Saving data..."
invoker.setCommand(deleteCommand);
invoker.executeCommand(); // 输出: "Deleting data..."

在这个示例中,有四个主要类:CommandSaveCommandDeleteCommand 和 Receiver

  • Command 是一个抽象类,定义了一个 execute() 方法,但并不实现该方法。这意味着任何继承 Command 的具体类都需要实现自己的 execute() 方法。
  • SaveCommand 和 DeleteCommand 是继承自 Command 的具体命令类。它们都实现了自己的 execute() 方法,分别调用 Receiver 对象的 save() 和 delete() 方法。
  • Receiver 类定义了两个方法:save() 和 delete(),分别代表数据的保存和删除操作。
  • Invoker 类负责处理命令。它有一个 command 属性,可以设置具体的命令对象,并有一个 executeCommand() 方法来执行命令。

示例的使用部分演示了如何使用这些类。首先,创建一个 Receiver 对象,然后创建两个命令对象 saveCommand 和 deleteCommand,它们都接受同一个 Receiver 对象作为参数。接着,创建一个 Invoker 对象,并设置其命令为 saveCommand 和 deleteCommand。最后,通过调用 executeCommand() 方法来执行命令。

2. 键盘快捷键

在处理键盘快捷键时,命令模式可以帮助我们将具体操作封装成命令对象,并将其与特定的快捷键关联起来。

 
// 定义命令接口
class Command {execute() {throw new Error('execute() method must be implemented');}
}
// 定义具体命令类
class CopyCommand extends Command {constructor(receiver) {super();this.receiver = receiver;}execute() {this.receiver.copy();}
}
class PasteCommand extends Command {constructor(receiver) {super();this.receiver = receiver;}execute() {this.receiver.paste();}
}
// 定义接收者类
class Receiver {copy() {console.log('Copying text...');// 执行复制操作的逻辑}paste() {console.log('Pasting text...');// 执行粘贴操作的逻辑}
}
// 定义调用者类
class Invoker {constructor() {this.commands = {};}setCommand(key, command) {this.commands[key] = command;}executeCommand(key) {if (this.commands[key]) {this.commands[key].execute();}}
}
// 使用示例
const receiver = new Receiver();
const copyCommand = new CopyCommand(receiver);
const pasteCommand = new PasteCommand(receiver);
const invoker = new Invoker();
invoker.setCommand('Ctrl+C', copyCommand);
invoker.setCommand('Ctrl+V', pasteCommand);
invoker.executeCommand('Ctrl+C'); // 输出: "Copying text..."
invoker.executeCommand('Ctrl+V'); // 输出: "Pasting text..."

上述示例中定义了一个抽象的命令类 Command,其中包含一个 execute() 方法。具体的命令类 CopyCommand 和 PasteCommand 继承自 Command 类,并实现了各自的 execute() 方法。

然后定义了一个接收者类 Receiver,其中包含 copy() 和 paste() 方法,分别表示复制和粘贴操作的具体逻辑。

接下来定义了一个调用者类 Invoker,其中包含一个 commands 对象用于存储命令对象,以及 setCommand() 和 executeCommand() 方法。setCommand() 方法用于将命令对象与特定的键值进行关联,executeCommand() 方法用于根据给定的键值执行对应的命令。

最后,通过实例化相关的类并进行调用,演示了命令模式的用法。创建了一个接收者对象 receiver,以及两个命令对象 copyCommand 和 pasteCommand。然后创建了一个调用者对象 invoker,并使用 setCommand() 方法将命令对象与对应的键值进行关联。最后通过调用 executeCommand() 方法执行对应的命令,输出相应的结果。

优点和缺点

优点
  1. 解耦操作和接收者:命令模式将操作封装成对象,使得发送者和接收者之间解耦,可以独立变化。
  2. 可扩展性:可以轻松地添加新的具体命令类,而无需修改现有代码。
  3. 支持撤销和重做:通过记录命令历史,可以实现撤销和重做操作。
缺点
  1. 可能导致类的数量增加:每个具体命令类都需要实现一个执行方法,可能会导致类的数量增加。
  2. 命令调用的开销:每个命令都需要创建一个对象,并将其传递给调用者执行,可能会带来一定的性能开销。

总结

命令模式是一种非常有用的设计模式,在前端开发中经常用于管理和执行操作。它通过将操作封装成对象,并将其作为参数传递、存储或记录,实现了优雅地管理和执行操作。通过使用命令模式,我们可以提高代码的可维护性和可扩展性。然而,在应用命令模式时需要权衡其带来的优缺点,并根据具体情况进行选择。

相关文章:

【前端设计模式】之命令模式

引言 命令设计模式是一种行为型设计模式,它允许你将命令封装到一个对象中,从而使你可以参数化不同的请求,以及存储、排队、重播和撤销请求。这种设计模式在处理用户界面操作、远程网络请求或其他需要异步执行的操作时非常有用。在前端开发中…...

用c++写一个高精度计算的乘法运算

这段代码是一个用C编写的程序&#xff0c;它实现了两个大整数的乘法运算。 #include<iostream> #include<cstdio> #include<cstring> using namespace std;int main(){char a1[101]"222",b1[101]"2";int a[101],b[101],c[10001],lena,l…...

UE5 ChaosVehicles载具 实现大漂移 (连载四)

载具设置成前驱模式 前轮摩擦力倍增x5 后轮摩擦力倍增x0.5...

基于Arrow的轻量线程池

基于Arrow的轻量线程池 大家好&#xff0c;我是光城&#xff0c;最近花了几周业余时间&#xff0c;开发出这款轻量线程池&#xff0c;代码也全部开源啦&#xff0c;欢迎大家star。 本线程池的设计与实现会有涉及非常多的知识&#xff0c;这些内容也都会以视频的方式分享在知识星…...

泛微OA E-Office V10 OfficeServer 任意文件上传漏洞复现

声明 本文仅用于技术交流&#xff0c;请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任。 漏洞简介 泛微e-ofice是一款标准化的协同0A办公软件&#xff0c;泛微 …...

spring-cloud-starter-gateway踩坑

1.bean of type org.springframework.http.codec.ServerCodecConfigurer that could not be found. 需要将项目中用到的spring-boot-starter-web依赖给去掉 去掉以下的 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-bo…...

视频SDK开发,多平台SDK快速接入

随着科技的不断发展&#xff0c;视频已经成为了企业业务中不可或缺的一部分。无论是在线教育、企业培训还是产品展示&#xff0c;视频都发挥着至关重要的作用。为了满足企业对视频应用的需求&#xff0c;美摄视频SDK应运而生&#xff0c;为企业提供了一站式的视频解决方案。 一…...

面试官:如何理解CDN?说说实现原理?

一、是什么 CDN (全称 Content Delivery Network)&#xff0c;即内容分发网络 构建在现有网络基础之上的智能虚拟网络&#xff0c;依靠部署在各地的边缘服务器&#xff0c;通过中心平台的负载均衡、内容分发、调度等功能模块&#xff0c;使用户就近获取所需内容&#xff0c;降…...

C语言 牛客网习题 10.20 day2

1.求最小公倍数 正整数A和正整数B 的最小公倍数是指 能被A和B整除的最小的正整数值&#xff0c;设计一个算法&#xff0c;求输入A和B的最小公倍数。 1≤a, b≤100000 输入描述&#xff1a; 输入两个正整数A和B。 输出描述&#xff1a; 输出A和B的最小公倍数。 #include <st…...

SpringCloud: sentinel热点参数限制

一、定义controller package cn.edu.tju.controller;import com.alibaba.csp.sentinel.annotation.SentinelResource; import com.alibaba.csp.sentinel.slots.block.BlockException; import org.springframework.web.bind.annotation.PathVariable; import org.springframewo…...

PDF编辑阅读 PDF Expert v3.5.2

PDF Expert是由Readdle开发的一款专业的PDF编辑和阅读工具。它可以帮助用户在Mac、iPad和iPhone等设备上查看、注释、编辑、填写和签署PDF文档。 以下是PDF Expert的特点&#xff1a; PDF编辑&#xff1a;PDF Expert提供了丰富的PDF编辑功能&#xff0c;包括添加、删除、移动…...

新技术:WEB组态能页面嵌套、属性继承吗?

目前市面上的工业组态或数据大屏工具有不少&#xff0c;也有很多0代码、无代码、低代码、零代码、低代码概念。 有没有可以支持图纸嵌套、属性暴露的&#xff1f;或者说页面任意嵌套、属性多继承暴露到上层&#xff1f; 比如页面A有输入框&#xff0c;页面B有对话框&#xff…...

【C++ Primer Plus学习记录】复习题

1.如何声明下述数据&#xff1f; a.actor是由30个char组成的数组。 char actor[30]; b.betsie是由100个short组成的数组。 short betsie[100]; c.chuck是由13个float组成的数组。 flaot chuck[13]; d.dipsea是由64个long double组成的数组。 long double dipsea[64]; …...

【LeetCode】62. 不同路径

1 问题 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径&#xff1f…...

【lesson13】进程地址空间收尾

文章目录 进程地址空间存在的原因原因一原因二原因三 重新理解什么是挂起&#xff1f; 进程地址空间存在的原因 原因一 凡是非法访问或者映射&#xff0c;OS都会识别到&#xff0c;并终止该进程。 例子&#xff1a; 我们会发现我们定义的字符串常量只有只读权限&#xff0c;…...

Microsoft Edge中使用开源的ChatGPT

一、双击打开浏览器 找到&#xff1a;扩展&#xff0c;打开 二、打开Microsoft Edge加载项 三、Move tab新标签 获取免费ChatGPT 四、启用Move tab。启用ChatGPT。 扩展 管理扩展 启用 五、新建标签页&#xff0c;使用GPT 六、使用举例 提问 GPT回复...

【C语言精髓之指针】结构体指针(->与.两个运算符的区别)

/*** file * author jUicE_g2R(qq:3406291309)————彬(bin-必应)* 通信与信息专业大二在读 * copyright 2023.10* COPYRIGHT 原创技术笔记&#xff1a;转载需获得博主本人同意&#xff0c;且需标明转载源* language C/C* IDE Base on Mic…...

SpringCloud 微服务全栈体系(一)

第一章 认识微服务 随着互联网行业的发展&#xff0c;对服务的要求也越来越高&#xff0c;服务架构也从单体架构逐渐演变为现在流行的微服务架构。这些架构之间有怎样的差别呢&#xff1f; 一、单体架构 单体架构&#xff1a;将业务的所有功能集中在一个项目中开发&#xff…...

Echarts自定义柱状图

目录 效果图 echarts官网找相似图 将柱状图引入html页面中 自定义柱状图 将不需要的属性删除 ​编辑 修改图形大小 grid 不显示x轴 ​编辑 不显示y轴线和相关刻度 ​编辑 y轴文字的颜色设置为自己想要的颜色 修改第一组柱子相关样式&#xff08;条状&#xff09; …...

LuatOS-SOC接口文档(air780E)-- ioqueue - io序列操作

ioqueue.init(hwtimer_id,cmd_cnt,repeat_cnt) 初始化一个io操作队列 参数 传入值类型 解释 int 硬件定时器id&#xff0c;默认用0&#xff0c;根据实际MCU确定&#xff0c;air105为0~5&#xff0c;与pwm共用&#xff0c;同一个通道号不能同时为pwm和ioqueue int 一个完…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时&#xff0c;没有加载所有类库。插件运行过程中用到某个类库&#xff0c;会从CAD的安装目录找&#xff0c;找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库&#xff0c;就用插件程序加载进…...