前端设计模式之旅:命令模式

在这里插入图片描述

引言

在这里插入图片描述

使用命令模式,我们可以将执行特定任务的对象与调用该方法的对象解耦。

核心思想

命令模式的核心思想是将请求封装成一个对象,从而使请求的发起者和请求的执行者解耦。

  • 请求的发起者只需要知道如何创建命令对象并将其传递给请求者,而不需要知道命令对象的具体实现细节。

  • 命令模式还支持可撤销操作,因为命令对象可以保存执行前的状态,并在需要时恢复状态。这样,可以通过撤销命令对象来撤销之前的操作。

适用场景

1. 需要将请求发送者和接收者解耦的场景

命令模式可以将请求封装成对象,从而使得请求的发送者和接收者之间解耦,使得系统更加灵活。

2. 需要支持撤销和重做操作的场景

命令模式可以将请求封装成对象,并提供撤销和重做操作,从而使得系统更加灵活和可靠。

3. 需要支持事务操作的场景

命令模式可以将多个请求封装成一个事务,从而保证事务的原子性和一致性。

4. 需要支持日志和审计功能的场景

命令模式可以将请求封装成对象,并记录请求的执行情况,从而支持日志和审计功能。

5. 需要支持队列请求的场景

命令模式可以将请求封装成对象,并将请求放入队列中,从而支持队列请求的场景。

案例实践

在这里插入图片描述

假设我们有一个简单的计算器,它可以执行加、减、乘、除四种操作。

我们可以使用命令模式来实现这个计算器,将每个操作封装成一个命令对象,然后将命令对象传递给计算器,从而实现不同的操作。

整体步骤

  1. 第一步:我们定义一个命令接口,它包含一个execute方法
  2. 第二步:我们定义四个具体的命令类,分别对应加、减、乘、除四种操作
  3. 第三步:我们定义一个计算器类,它包含一个命令队列和一个执行命令的方法
  4. 第四步:使用这些类来实现一个简单的计算器

第一步,我们定义一个命令接口,它包含一个execute方法:

class Command {execute() {}
}

第二步,我们定义四个具体的命令类,分别对应加、减、乘、除四种操作:

加法操作:AddCommand类继承Command

class AddCommand extends Command {constructor(receiver, value) {super();this.receiver = receiver;this.value = value;}execute() {this.receiver.add(this.value);}
}

减法操作:SubCommand类继承Command

class SubCommand extends Command {constructor(receiver, value) {super();this.receiver = receiver;this.value = value;}execute() {this.receiver.sub(this.value);}
}

乘法操作:MulCommand类继承Command

class MulCommand extends Command {constructor(receiver, value) {super();this.receiver = receiver;this.value = value;}execute() {this.receiver.mul(this.value);}
}

除法操作:DivCommand类继承Command

class DivCommand extends Command {constructor(receiver, value) {super();this.receiver = receiver;this.value = value;}execute() {this.receiver.div(this.value);}
}

其中,每个命令类都包含一个接收者对象和一个操作值,execute方法会调用接收者对象的相应方法来执行操作。

第三步,我们定义一个计算器类,它包含一个命令队列和一个执行命令的方法:

// 计算器类
class Calculator {constructor() {this.commands = [];this.current = 0;}
// addCommand方法用于将命令对象添加到命令队列中addCommand(command) {this.commands.push(command);}
// executeCommand方法用于执行当前命令executeCommand() {this.commands[this.current].execute();this.current++;}
// undo方法用于撤销上一个命令undo() {this.commands[this.current - 1].execute();this.current--;}
// redo方法用于重做上一个命令redo() {this.commands[this.current].execute();this.current++;}
}

其中,addCommand方法用于将命令对象添加到命令队列中,executeCommand方法用于执行当前命令,undo方法用于撤销上一个命令,redo方法用于重做上一个命令。

第四步,使用这些类来实现一个简单的计算器:

const calculator = new Calculator();
const receiver = {value: 0,add: function (value) {this.value += value;console.log(`Add ${value}, result: ${this.value}`);},sub: function (value) {this.value -= value;console.log(`Sub ${value}, result: ${this.value}`);},mul: function (value) {this.value *= value;console.log(`Mul ${value}, result: ${this.value}`);},div: function (value) {this.value /= value;console.log(`Div ${value}, result: ${this.value}`);},
};const addCommand = new AddCommand(receiver, 10);
const subCommand = new SubCommand(receiver, 5);
const mulCommand = new MulCommand(receiver, 2);
const divCommand = new DivCommand(receiver, 4);calculator.addCommand(addCommand);
calculator.addCommand(subCommand);
calculator.addCommand(mulCommand);
calculator.addCommand(divCommand);

具体执行及其结果:

calculator.executeCommand(); // Add 10, result: 10
calculator.executeCommand(); // Sub 5, result: 5
calculator.executeCommand(); // Mul 2, result: 10
calculator.executeCommand(); // Div 4, result: 2.5calculator.undo(); // Div 4, result: 10
calculator.undo(); // Mul 2, result: 20
calculator.undo(); // Sub 5, result: 25
calculator.undo(); // Add 10, result: 35calculator.redo(); // Add 10, result: 10
calculator.redo(); // Sub 5, result: 5
calculator.redo(); // Mul 2, result: 10
calculator.redo(); // Div 4, result: 2.5

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/227572.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

极坐标下的牛拉法潮流计算57节点MATLAB程序

微❤关注“电气仔推送”获得资料(专享优惠) 潮流计算: 潮流计算是根据给定的电网结构、参数和发电机、负荷等元件的运行条件,确定电力系统各部分稳态运行状态参数的计算。通常给定的运行条件有系统中各电源和负荷点的功率、枢纽…

贪心算法:买卖股票的最佳时机II 跳跃游戏 跳跃游戏II

122.买卖股票的最佳时机II 思路: 想要获得利润,至少要以两天为一个交易单元,因为两天才会有股价差。因此可以将最终利润进行分解,如prices[3] - prices[0] (prices[3] - prices[2]) (prices[2] - prices[1]) (prices[1] - pr…

【Mars3d-ModelEntity】实现gltf模型不随地图缩放而改变大小

需求场景: 1.实现gltf模型不随地图缩放而改变大小 相关代码: const graphic new mars3d.graphic.ModelEntity({ name: "警车", position: [116.346929, 30.861947, 401.34], style: { url: "//data.mars3d.cn/gltf/mars/jingche/jingc…

python界面开发,使用wxpython库

入门学习Python时,使从接触一个项目开始,当时需要我开发一个界面,当时综合考量之后,最终选择了今天要分享的内容部分,也就是使用Python来开发,主要使用到的是Python库——wxPython库来进行界面开发&#xf…

论文阅读:Lidar Annotation Is All You Need

目录 概要 Motivation 整体架构流程 技术细节 小结 概要 论文重点在探讨利用点云的地面分割任务作为标注,直接训练Camera的精细2D分割。在以往的地面分割任务中,利用Lidar来做地面分割是目前采用激光雷达方案进行自动驾驶的常见手段。来自Evocargo …

phpstudy是什么?

PHPStudy 是一个集成环境工具,它将 PHP 开发所需的软件,如 Apache(Web服务器)、MySQL(数据库服务器)、PHP(脚本语言)等打包在一起,以便用户能够轻松安装和配置这些软件&a…

UniGUI 之UniDBGrid

目录 1]DataSource设置 2]显示MEMO类型里的文字 3]显示悬浮提示 4]显示当前记录及总记录数 5]读取所有记录,及分页 6]在前面加上序号列 7]不显示标题栏 8]列排序 9]编辑 和 更新 数据 10]获得某单元格里的内容 11]标题别名 12]将某列设置为CheckBox格式 13]列标题…

Redis设计与实现之字符串哈希表列表

目录 一、字符串 1、字符串编码 2、编码的选择 二、哈希表 1、字典编码的哈希表 2、压缩列表编码的哈希表 3、编码的选择 4、哈希命令的实现 三、列表 1、 编码的选择 2、 列表命令的实现 3、阻塞的条件 4、 阻塞 5、 阻塞因 LPUSH 、RPUSH 、LINSERT 等添加命令而…

【C语言】操作符详解(五)

目录 操作符的属性:优先级,结合性 优先级 结合性 表达式求值 整形提升 算术转换 问题表达式解析 表达式1 表达式2 表达式3 总结 操作符的属性:优先级,结合性 优先级 ⭐优先级:优先级指的是,如果一…

网络安全——Iptables防DDoS攻击实验

一、实验目的要求: 二、实验设备与环境: 三、实验原理: 四、实验步骤: 五、实验现象、结果记录及整理: 六、分析讨论与思考题解答: 一、实验目的要求: 1、掌握常见DDoS攻击SYN Flood的攻击…

Cmake基础(4)

这篇文章在上一篇的基础之上应用多文件,即一个项目中添加多个文件 文章目录 GLOBsource_group排除文件 上一篇文章的cmake基本不变,这篇文章的重点在于add_executable(${EXECUTABLE_NAME} main.cpp) GLOB file(GLOB cpp_list ${CMAKE_CURRENT_SOURCE_…

Arrays.asList()方法:陷阱与解决之道

在Java编程中,Arrays类提供了一系列用于操作数组的实用方法。其中,​Arrays.asList()​方法是一个常用的方法,用于快速将数组转换为List集合。然而,这个方法存在一些潜在的陷阱,可能导致出现意外的行为。本文将介绍​A…

h5 hdf5 pytables 数据库 减少空间占用的方法

方法来源:https://forum.hdfgroup.org/t/hdf5-deleting-datasets-and-recovering-space/1293 h5 数据库,在删除一些数据,表,数组后,无法变小; 或是在多次读写后,会越来越大,并且有一…

python:import 自定义包或者.py文件时出现:ModuleNotFoundError: no module named 的问题解决

问题: 在以下的示例中,wuHanMoviesSprider.py文件,想要import引用指定目录下的Items类时,出现无法识别module模块的问题(from 的引用处报错)。 原因分析: 正常情况下,被引用的包(或目录)中存在一个空文件…

vue 实现点击复制文本到剪贴板

vue 实现点击复制文本到剪贴板 共四种方法 1. navigator.clipboard.writeText该方法需要在安全域下才能够使用&#xff0c;比如&#xff1a;https 协议的地址、127.0.0.1、localhost <template><div><el-button type"primary" click"btn1"…

Docker 部署 Lobe Chat 服务

拉取最新版本的 Lobe Chat 镜像&#xff1a; $ sudo docker pull lobehub/lobe-chat:latest使用以下命令来运行 Lobe Chat 容器: $ sudo docker run -d --name lobe-chat -p 10084:3210 -e OPENAI_API_KEYsk-xxxx -e OPENAI_PROXY_URLhttps://api.openai.com/v1 -e ACCESS_CO…

ES6 面试题 | 13.精选 ES6 面试题

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

普冉(PUYA)单片机开发笔记(10): I2C通信-配置从机

概述 I2C 常用在某些型号的传感器和 MCU 的连接&#xff0c;速率要求不高&#xff0c;距离很短&#xff0c;使用简便。 I2C的通信基础知识请参见《基础通信协议之 IIC详细讲解 - 知乎》。 PY32F003 可以复用出一个 I2C 接口&#xff08;PA3&#xff1a;SCL&#xff0c;PA2&a…

C++ 运算符重载

目录 前言 算术运算符重载 加号运算符 位运算符重载 左移运算符 自增自减运算符重载 前置自增运算符 后置自增运算符 赋值运算符重载 等号赋值运算符重 关系运算符重载 相等 不等 函数调用运算符重载 总结 前言 在C中&#xff0c;运算符重载是一种强大的特性…

数据可视化---柱状图

import matplotlib.pyplot as plt import numpy as npdef plot_bar_chart(data, labels, colorsNone, title"Bar Chart", xlabel"X-Axis", ylabel"Y-Axis"):"""绘制柱状图&#xff0c;并在柱子上显示数量和比例。:param data: 包…