掌握设计模式:深入了解命令模式的优雅调度与行为解耦

命令模式是一种行为设计模式,其目的是将请求发送者和接收者解耦,从而允许发送者发送请求,而无需知道请求的具体处理方式。在命令模式中,请求被封装为一个对象,这个对象包含了执行请求所需的所有信息,包括调用方法、参数等。这样,请求的发送者只需知道如何发送命令对象,而不需要关心命令的具体执行。

关键角色和概念:

命令接口(Command): 声明了执行命令的方法 execute(),以及可能的撤销方法 undo() 和重做方法 redo()。这个接口可以有多个具体实现类,每个类代表不同的命令。
具体命令(ConcreteCommand): 实现了命令接口,负责执行具体的操作。它通常包含一个接收者对象,通过调用接收者的方法来完成实际的工作。
调用者(Invoker): 请求的发送者,负责将命令发送给接收者。它并不知道命令的具体执行细节,只是负责发送请求。
接收者(Receiver): 实际执行命令操作的对象。命令对象通常会包含一个接收者,通过调用接收者的方法来完成命令的执行。
客户端(Client): 创建命令对象、接收者对象以及调用者对象的地方。客户端将命令对象与调用者关联,并发送请求。

命令模式的优点包括:

解耦请求发送者和接收者: 命令模式将请求的发送者和接收者解耦,使得它们不需要直接了解对方。这提高了系统的灵活性和可维护性。

支持撤销和重做: 通过在命令对象中添加 undo() 和 redo() 方法,可以轻松实现撤销和重做操作。

容易扩展: 可以轻松添加新的命令类,无需修改现有的代码。

命令模式通常在需要对请求进行参数化、排队、记录日志、支持撤销和重做等场景中发挥作用。

简易命令模式示例:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Command Pattern Demo</title></head><body><!-- 页面标题 --><h1>Command Pattern Demo</h1><!-- 按钮触发灯的开关命令 --><button onclick="pressLightButton()">Toggle Light</button><!-- 按钮触发风扇的开关命令 --><button onclick="pressFanButton()">Toggle Fan</button><!-- 按钮触发撤销操作 --><button onclick="undo()">Undo</button><!-- 按钮触发重做操作 --><button onclick="redo()">Redo</button><!-- 图片显示灯和风扇状态 --><div><imgid="light"src="./light.png"height="90"style="filter: grayscale(100%)"/><imgid="fan"src="./fan.png"height="90"style="filter: grayscale(100%)"/></div><!-- 显示命令执行信息的区域 --><div id="output"></div><script>// 命令接口class Command {execute() {}undo() {}redo() {}}// 具体命令 - 打开灯class LightOnCommand extends Command {constructor(light) {super();this.light = light;}execute() {this.light.turnOn();addCommandToHistory(this);}undo() {this.light.turnOff();}redo() {this.light.turnOn();}}// 具体命令 - 关闭灯class LightOffCommand extends Command {constructor(light) {super();this.light = light;}execute() {this.light.turnOff();addCommandToHistory(this);}undo() {this.light.turnOn();}redo() {this.light.turnOff();}}// 具体命令 - 打开风扇class FanOnCommand extends Command {constructor(fan) {super();this.fan = fan;}execute() {this.fan.turnOn();addCommandToHistory(this);}undo() {this.fan.turnOff();}redo() {this.fan.turnOn();}}// 具体命令 - 关闭风扇class FanOffCommand extends Command {constructor(fan) {super();this.fan = fan;}execute() {this.fan.turnOff();addCommandToHistory(this);}undo() {this.fan.turnOn();}redo() {this.fan.turnOff();}}// 接收者 - 灯class Light {constructor() {this.isOn = false;}turnOn() {this.isOn = true;// 获取灯的 DOM 元素并设置为彩色(非灰度)const dom = document.getElementById("light");dom.style.filter = "grayscale(0%)";// 更新信息updateOutput("灯被打开了");}turnOff() {this.isOn = false;// 获取灯的 DOM 元素并设置为灰度const dom = document.getElementById("light");dom.style.filter = "grayscale(100%)";// 更新信息updateOutput("灯被关闭了");}}// 接收者 - 风扇class Fan {constructor() {this.isOn = false;}turnOn() {this.isOn = true;// 获取风扇的 DOM 元素并设置为彩色(非灰度)const dom = document.getElementById("fan");dom.style.filter = "grayscale(0%)";// 更新信息updateOutput("风扇被打开了");}turnOff() {this.isOn = false;// 获取风扇的 DOM 元素并设置为灰度const dom = document.getElementById("fan");dom.style.filter = "grayscale(100%)";// 更新信息updateOutput("风扇被关闭了");}}// 创建灯和风扇的实例const light = new Light();const fan = new Fan();// 创建具体命令实例const lightOnCommand = new LightOnCommand(light);const lightOffCommand = new LightOffCommand(light);const fanOnCommand = new FanOnCommand(fan);const fanOffCommand = new FanOffCommand(fan);// 命令历史记录和索引let commandHistory = [];let historyIndex = -1;// 将命令添加到历史记录function addCommandToHistory(command) {if (commandHistory.length >= 100) commandHistory.shift();commandHistory.push(command);historyIndex = commandHistory.length - 1;}// 撤销操作function undo() {if (historyIndex >= 0) {// 执行当前索引对应的命令的撤销操作commandHistory[historyIndex].undo();historyIndex--;}}// 重做操作function redo() {if (historyIndex < commandHistory.length - 1) {// 增加历史索引并执行对应命令的操作historyIndex++;commandHistory[historyIndex].redo();}}// 按钮点击触发灯的开关命令function pressLightButton() {if (light.isOn) {lightOffCommand.execute();} else {lightOnCommand.execute();}}// 按钮点击触发风扇的开关命令function pressFanButton() {if (fan.isOn) {fanOffCommand.execute();} else {fanOnCommand.execute();}}// 更新页面上显示命令执行信息的区域function updateOutput(message) {const outputDiv = document.getElementById("output");outputDiv.innerHTML = `<p>${message}</p>`;}</script></body>
</html>

运行演示:

命令模式

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

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

相关文章

spring源码解析(六)

bean对象的初始化及销毁时&#xff0c;执行相关操作的几种方式。 package com.test;import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.annotation.AnnotationConfi…

解析器:request.body、request.POST、request.data

request.POST与request.body&#xff1a; django中的request.POST只能取到Content-Type(请求头)为application/x-www-form-urlencoded(form表单默认格式)的数据&#xff0c;如果请求头为application/json(json格式)&#xff0c;multipart/form-data(文件)等格式无法取到&#x…

5个你不能错过的在线教育开源项目

教育行业的蓬勃发展使得数字化教育成为一种日益受欢迎的趋势。在这个信息时代&#xff0c;小程序已经成为许多企业加速应用上线的理想选择。开源项目更是为教育行业的创业者和开发者提供了宝贵的资源&#xff0c;不仅能够降低开发成本&#xff0c;还能够快速搭建起强大的教育应…

Perfetto 使用 笔记

抓取命令 抓取 adb shell perfetto -o /data/misc/perfetto-traces/trace_file.perfetto-trace -t 10s sched freq idle am wm gfx view binder_driver hal dalvik camera input res memory导出命令 adb pull /data/misc/perfetto-traces/trace_file.perfetto-trace打开工具…

完全可降解支架行业分析:2025 年将达到3.444亿美元

完全可降解支架&#xff0c;也称为生物可吸收支架&#xff0c;是医疗器械市场上相对较新的发展。这些支架由会随着时间的推移分解并被人体吸收的材料制成&#xff0c;从而无需在达到其目的后进行手术移除。 市场分析&#xff1a;完全可降解支架的全球市场预计在未来几年将显着增…

LeetCode[102] [107] 二叉树层序遍历

Description&#xff1a;给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。解法&#xff1a; vector<vector<int>> levelOrder(TreeNode* root) {vector<vector<int>…

世邦通信SPON IP网络对讲广播系统未授权访问

产品介绍 世邦通信SPON IP网络对讲广播系统采用领先的IPAudio™技术,将音频信号以数据包形式在局域网和广域网上进行传送,是一套纯数字传输系统。 漏洞描述 spon IP网络对讲广播系统getuserdata.php存在未授权访问漏洞&#xff0c;攻击者可通过该漏洞在服务器端读取账户密码…

软件工程各种图

参考视频&#xff1a; 6 分钟学会 UML 类图_哔哩哔哩_bilibili 5 分钟学会 UML 时序图&#xff08;顺序图、序列图&#xff09;_哔哩哔哩_bilibili 3 分钟学会 UML 活动图_哔哩哔哩_bilibili 6 分钟学会 UML 用例图_哔哩哔哩_bilibili 是真的讲的非常好&#xff01;&#…

Aloha 机械臂的学习记录3——AWE:Pycharm运行代码记录

之前的博客创作了三偏关于Aloha_AWE的liunx终端指令运行代码的示例: Aloha 机械臂的学习记录——AWE&#xff1a;Bimanual Simulation Suite: https://blog.csdn.net/qq_54900679/article/details/134889183?spm1001.2014.3001.5502 Aloha 机械臂的学习记录1——AWE&#x…

Python 与 PySpark数据分析实战指南:解锁数据洞见

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流的小伙伴&#xff0c;请点击【全栈技术交流群】 数据分析是当今信息时代中至关重要的技能之一。…

【Spring Data JPA】根据动态查询条件、根据经纬度距离查询

根据动态条件 Query(nativeQuery true, value "select A.* " "from epidemic_case_info A where A.delete_flag 0 " "and (case " "when right(:distCode, 4) 0000 then A.dist_code like concat(substring(:distCode, 1, 2 ), %) &qu…

阿里云服务器被DDoS攻击怎么办

为了保证正常的网络服务&#xff0c;许多公司和组织都选择使用高效稳定的云服务器。然而&#xff0c;在互联网上的任何服务器都可能遭受DDoS攻击。DDoS攻击是一种臭名昭著的网络攻击&#xff0c;它旨在使网络服务器不可用&#xff0c;阻止合法用户访问网站以及其他网络服务。阿…

免费运维工具测评——深入使用牧云主机管理助手

作为一名运维&#xff0c;宝塔&#xff0c;Nezha 监控面板&#xff0c;WinSCP&#xff0c;Termius 都用过了&#xff0c;谈一下自己的感受&#xff1a; 安装绑定 微信扫码可直接登录&#xff0c;主页简洁清晰&#xff0c;即使是个人体验版也没有任何广告。 只需要复制命令在服…

基于神经网络的手写汉字提取与书写评分系统研究

相关源码和文档获取请私聊QQ:3106089953 论文目录结构 目 录 摘 要 I Abstract II 目 录 IV 第1章 绪论 1 1.1. 研究背景与意义 1 1.2. 国内外研究现状 2 1.2.1. 文本定位技术研究现状 2 1.2.2. 手写汉字识别研究现状 3 1.2.3. 汉字书写质量评价方法研究现状 4 1.3. 本文所做工…

Linux驱动开发(1)-最简单的字符设备驱动开发例子

1.简介 字符设备驱动&#xff1a;按照字节流进行读写操作的设备&#xff0c;例如点灯、按键、IIC、SPI、LCD。 Linux系统中一切皆文件&#xff0c;驱动加载成功&#xff0c;就会在/dev目录生成文件&#xff0c;对文件操作&#xff0c;则可实现对硬件操作。应用程序运行在用户…

Leetcode242有效的字母异位词(java实现,详细易懂想学会的进!!!)

今天给大家分享的题目是leetcode242有效的字母异位词 我们先看题目描述&#xff1a; Chatgpt中对于字母异位词的解释如下&#xff1a; 字母异位词是指由相同的字母组成但顺序不同的单词。换句话说&#xff0c;字母异位词具有相同的字母&#xff0c;只是排列顺序不同。 简单的将…

华云安攻击面发现及管理平台体验

省流&#xff1a; 无需【立即咨询】即可体验&#xff0c;开通即可查看演示数据&#xff0c;公开报价 界面&#xff1a; 界面简洁&#xff0c;要点清晰&#xff0c;可以清晰的看到暴露面及攻击面信息 功能&#xff1a; 资产发现&#xff1a;主域名发现、子域名发现、 IP 发现…

Set和Map

一、Set的介绍 1.1、Set相关文档介绍 cplusplus.com/reference/set/set/?kwset 1. set是按照一定次序存储元素的容器 2. 在set中&#xff0c;元素的value也标识它(value就是key&#xff0c;类型为T)&#xff0c;并且每个value必须是唯一的。 set中的元素不能在容器中修改…

时空序列问题的本质和底层逻辑

本质&#xff1a;Still need to polish this. 底层逻辑&#xff1a;Still need to polish this.See you pretty soon. Reference 【时空序列预测】什么是时空序列问题&#xff1f;这类问题主要应用了哪些模型&#xff1f;主要应用在哪些领域&#xff1f;_mb62b92582e5a0a的技…

青少年软件编程(C/C++)等级考试试卷(一级)2023年12月

202312 青少年软件编程&#xff08;C/C&#xff09;等级考试试卷&#xff08;一级&#xff09;电子学会真题 编程题 1.数的输入和输出&#xff08;2023.12&#xff09; 输入一个整数和双精度浮点数&#xff0c;先将浮点数保留2位小数输出&#xff0c;然后输出整数。 输入 …