设计模式8-命令模式

定义

        Command Partern: 将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。(核心思想是将“动作”与“执行者”解耦)

场景

  • GUI:操作将UI控件与业务逻辑解耦,一个命令可被多处复用。

  • 撤销/重做:通过记录命令历史和状态,实现操作的回逆。

  • 任务队列:实现任务的延迟执行和异步处理,解耦生产与消费。

  • 宏录制:使用组合模式将多个命令组合成一个宏命令。

  • 事务系统:提供原子操作和回滚机制。

  • 异步回调:封装未来需要执行的操作,实现模块间的解耦通信。

Java中的典型场景

  1. Swing/AWT事件处理:ActionListener本质是命令模式。

  2. 线程池:RunnableCallable任务封装了执行逻辑。

  3. 事务管理:数据库操作封装为可回滚的命令对象。

代码

import java.util.Stack;
// 文档编辑器的撤销和执行
// 命令接口
interface EditorCommand {void execute();void undo();
}// 接收者:文档
class Document {private StringBuilder content = new StringBuilder();public String getContent() {return content.toString();}public void insertText(String text) {content.append(text);System.out.println("插入文本: " + text + ",当前内容: " + content);}public void deleteText(int length) {if (length > content.length()) {length = content.length();}String deleted = content.substring(content.length() - length);content.delete(content.length() - length, content.length());System.out.println("删除文本: " + deleted + ",当前内容: " + content);}
}// 具体命令:插入文本
class InsertCommand implements EditorCommand {private Document document;private String text;public InsertCommand(Document doc, String text) {this.document = doc;this.text = text;}@Overridepublic void execute() {document.insertText(text);}@Overridepublic void undo() {document.deleteText(text.length());}
}// 调用者:编辑器
class TextEditor {private Stack<EditorCommand> commandHistory = new Stack<>();private Stack<EditorCommand> redoStack = new Stack<>();public void executeCommand(EditorCommand command) {command.execute();commandHistory.push(command);redoStack.clear(); // 执行新命令后清空重做栈}public void undo() {if (!commandHistory.isEmpty()) {EditorCommand command = commandHistory.pop();command.undo();redoStack.push(command);System.out.println("执行撤销操作");} else {System.out.println("没有可撤销的操作");}}public void redo() {if (!redoStack.isEmpty()) {EditorCommand command = redoStack.pop();command.execute();commandHistory.push(command);System.out.println("执行重做操作");} else {System.out.println("没有可重做的操作");}}
}// 测试类class TextEditorDemo {public static void main(String[] args) {Document doc = new Document();TextEditor editor = new TextEditor();System.out.println("=== 编辑文档过程 ===");editor.executeCommand(new InsertCommand(doc, "Hello "));editor.executeCommand(new InsertCommand(doc, "World "));editor.executeCommand(new InsertCommand(doc, "Java!"));System.out.println("\n=== 撤销操作 ===");editor.undo(); // 撤销插入"Java!"editor.undo(); // 撤销插入"World "System.out.println("\n=== 重做操作 ===");editor.redo(); // 重做插入"World "editor.redo(); // 重做插入"Java!"}
}

生活中的示例:文档编辑器撤销 (Undo) 和重做 (Redo) 功能,比如餐厅点餐系统的例子:服务员(调用者)接收顾客的点单(命令),然后交给厨房(接收者)执行。在比如家电遥控器:遥控器上的每个按钮都对应一个命令,按下按钮就执行相应操作(开、关、调节等)

命令模式代码

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

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

相关文章

数据结构(顺序表力扣刷题)

1.移除元素 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。 假设 nums 中不等于 val 的元素数量为 k&#xff0c;要通过此题&#xff0c;您需要执行以下操作&…

机器学习 - Kaggle项目实践(6)Dogs vs. Cats Redux: Kernels Edition 猫狗二分类

Dogs vs. Cats Redux: Kernels Edition | Kaggle 任务&#xff1a;给定猫狗图像数据集 进行二分类。 Cats or Dogs - using CNN with Transfer Learning | Kaggle&#xff08;参考&#xff09; Cats or Dogs | Kaggle &#xff08;我的kaggle&#xff09; 本文介绍了使用Re…

基础的汇编指令

目录 1、接上一个csdn特殊功能寄存器 1.1CPSR寄存器 1.2SPSR寄存器 1.3CPSR寄存器的高四位和第四位 ​编辑 2、汇编指令的分类 3、汇编指令的基本格式 4、数据搬移指令&#xff08;赋值指令&#xff09; 4.1指令码 4.2指令格式 4.3测试代码 4.5立即数 4.6ldr伪指令 …

Docker实战避坑指南:从入门到精通

摘要&#xff1a;文人结合自身微服务实践&#xff0c;系统梳理从安装适配、镜像拉取&#xff0c;到运行配置、构建优化、多容器编排、数据持久化、监控运维等 Docker 全流程高频踩坑点&#xff0c;给出可落地的解决方案&#xff0c;帮助读者快速规避同类问题并提升容器化效率。…

《Bishop PRML》10.1. Variational Inference(2)理解VAE

通过VAE与AE理解变分分布的变量 如何理解变分推断公式中,Z和X的含义是什么? 知乎 变分自编码器VAE的数学原理。 csdn 变分自编码器(VAE)的数学原理以及实现 Loss functions in Variational Autoencoders (VAEs) 一文解释 VAE+ELBO AE的编码和解码是确定性的。VAE的解码过程…

函数调用中的初始化与赋值——深入理解C++对象的生命周期

技术博客&#xff1a;函数调用中的初始化与赋值——深入理解C对象的生命周期引言在C编程中&#xff0c;理解函数调用过程中参数传递、对象创建和返回值处理的细节对于编写高效且无误的代码至关重要。本文将通过一个具体的例子来探讨函数调用时实参到形参的转换过程&#xff0c;…

矩阵微积分的链式法则(chain rule)

矩阵微积分的链式法则&#xff08;chain rule&#xff09;与标量情况一样&#xff0c;用于求复合函数的导数&#xff0c;但由于涉及矩阵和向量的求导&#xff0c;维度匹配和布局约定&#xff08;numerator-layout vs. denominator-layout&#xff09;必须格外小心。下面给出常见…

网络编程4-并发服务器、阻塞与非阻塞IO、信号驱动模型、IO多路复用..

一、并发服务器1、单循环服务器&#xff08;顺序处理&#xff09; 一次只能处理一个客户端连接&#xff0c;只有当前客户端断开连接后&#xff0c;才能接受新的客户端连接2、多进程/多线程并发服务器while(1) {connfd accept(listenfd);pid fork(); // 或 pthread_cr…

在 WSL2-NVIDIA-Workbench 中安装Anaconda、CUDA 13.0、cuDNN 9.12 及 PyTorch(含完整环境验证)

在 WSL-NVIDIA-Workbench&#xff08;NVIDIA AI Workbench & Ubuntu 22.04&#xff09;中 安装 Anaconda、CUDA 13.0、cuDNN 9.12 及 PyTorch 步骤也可参阅&#xff1a; 在WSL2-Ubuntu中安装Anaconda、CUDA13.0、cuDNN9.12及PyTorch&#xff08;含完整环境验证&#xf…

Shell编程核心入门:参数传递、运算符与流程控制全解析

Shell编程核心入门&#xff1a;参数传递、运算符与流程控制全解析 在Linux/Unix系统中&#xff0c;Shell作为命令解释器和脚本语言&#xff0c;是自动化运维、批量处理任务的核心工具。掌握Shell脚本的参数传递、运算符使用和流程控制&#xff0c;能让你从“手动执行命令”升级…

如何用 Kotlin 在 Android 手机开发一个应用程序获取网络时间

使用 NTP 协议获取网络时间在 build.gradle 文件中添加以下依赖&#xff1a;implementation commons-net:commons-net:3.6创建 NTP 时间获取工具类&#xff1a;import org.apache.commons.net.ntp.NTPUDPClient import org.apache.commons.net.ntp.TimeInfo import java.net.In…

python智慧交通数据分析可视化系统 车流实时检测分析 深度学习 车流量实时检测跟踪 轨迹跟踪 毕业设计✅

博主介绍&#xff1a;✌全网粉丝50W&#xff0c;前互联网大厂软件研发、集结硕博英豪成立软件开发工作室&#xff0c;专注于计算机相关专业项目实战6年之久&#xff0c;累计开发项目作品上万套。凭借丰富的经验与专业实力&#xff0c;已帮助成千上万的学生顺利毕业&#xff0c;…

计算机视觉第一课opencv(四)保姆级教学

目录 简介 一、轮廓检测 1.查找轮廓的API 2.代码分析 2.1.图像二值化处理 2.2轮廓检测 2.3轮廓绘制 2.4轮廓面积计算 2.5轮廓周长计算 2.6筛选特定面积的轮廓 2.7查找最大面积的轮廓 2.8绘制轮廓的外接圆 2.9绘制轮廓的外接矩形 二、轮廓的近似 三、模板匹配 简…

基于Vue2+elementUi实现树形 横向 合并 table不规则表格

1、实现效果 共N行&#xff0c;但是每一列对应的单元格列数固定&#xff0c;行数不固定2、实现方式说明&#xff1a;使用的是vue2 elementUI表格组件 js实现<template><div class"table-container" ><el-table height"100%" :span-metho…

深度学习在计算机视觉中的应用:对象检测

引言 对象检测是计算机视觉领域中的一项基础任务&#xff0c;目标是在图像或视频帧中识别和定位感兴趣的对象。随着深度学习技术的发展&#xff0c;对象检测的准确性和效率都有了显著提升。本文将详细介绍如何使用深度学习进行对象检测&#xff0c;并提供一个实践案例。 环境准…

node.js 安装步骤

在Node.js中安装包通常通过npm(Node Package Manager)来完成,这是Node.js的包管理工具。以下是安装Node.js和通过npm安装包的基本步骤: 1. 安装Node.js 方法一:使用nvm(Node Version Manager) 推荐使用nvm来安装Node.js,因为它允许你安装多个Node.js版本,并轻松地在…

面试-故障案例解析

一、NFS故障&#xff0c;造成系统cpu使用率低而负载极高。故障概述: 公司使用NFS为web节点提供共享存储服务,某一天下午发现web节点CPU使用率低,而负载极高.登录web节点服务器排查发现后段NFS服务器故障. 影响范围: 网站看不到图片了。 处理流程: 通过ssh登录NFS服务…

医疗AI时代的生物医学Go编程:高性能计算与精准医疗的案例分析(一)

摘要: 随着高通量测序、医学影像和电子病历等生物医学数据的爆炸式增长,对高效、可靠、可扩展的计算工具需求日益迫切。Go语言凭借其原生并发模型、卓越的性能、简洁的语法和强大的标准库,在生物医学信息学领域展现出独特优势。本文以“生物医学Go编程探析”为主题,通过三个…

针对 “TCP 连接建立阶段” 的攻击

针对 “TCP 连接建立阶段” 的攻击一、定义二、共性防御思路三、攻击手段3.1、SYN 洪水攻击&#xff08;SYN Flood&#xff09;3.2、Land 攻击&#xff08;Land Attack&#xff09;一、定义 什么是针对 “TCP 连接建立阶段” 的攻击&#xff1f;核心特征是利用 TCP “三次握手…

聊一聊 单体分布式 和 微服务分布式

微服务 与 单体架构对比维度单体架构微服务架构​​架构本质​​一个单一的、功能齐全的应用程序一组​​小型、独立​​的服务集合​​开发​​团队工作在同一个代码库&#xff0c;易产生冲突。技术栈统一。每个服务可以由​​ 独立的小团队 ​​负责&#xff0c;允许使用​​…