一、核心定义与设计思想

命令模式通过对象化请求,将操作的具体实现细节封装在命令对象中,使得调用者(Invoker)无需直接依赖接收者(Receiver),仅需通过命令对象间接调用。这种设计支持以下能力:

  1. 解耦请求发送者与执行者:调用者仅与命令接口交互,无需了解接收者的实现细节。
  2. 支持扩展性与灵活性:新增命令只需实现接口,符合开闭原则。
  3. 实现高级功能:如撤销(Undo)、重做(Redo)、事务管理及日志记录。

二、模式结构与角色

命令模式包含以下核心角色:

  1. Command(抽象命令接口)
    声明执行操作的统一接口,通常包含execute()方法,部分场景扩展undo()方法以支持撤销。
    public interface Command { void execute(); void undo(); // 可选
    }
    
  2. ConcreteCommand(具体命令类)
    实现命令接口,持有接收者的引用并调用其方法。例如:
    public class LightOnCommand implements Command {private Light receiver;public LightOnCommand(Light receiver) { this.receiver = receiver; }public void execute() { receiver.turnOn(); }
    }
    
  3. Receiver(接收者)
    实际执行操作的对象,例如电灯、文本编辑器等业务逻辑实现类。
  4. Invoker(调用者)
    触发命令执行的入口,不关心命令具体实现。例如遥控器或按钮:
    public class RemoteControl {private Command command;public void pressButton() { command.execute(); }
    }
    
  5. Client(客户端)
    创建具体命令对象并绑定接收者,将其传递给调用者。

三、代码示例与实现

场景:遥控器控制家电(经典案例)

  1. 定义接收者
    class Light {public void turnOn() { System.out.println("灯已开启"); }public void turnOff() { System.out.println("灯已关闭"); }
    }
    
  2. 实现具体命令
    class LightOnCommand implements Command {private Light light;public LightOnCommand(Light light) { this.light = light; }public void execute() { light.turnOn(); }
    }
    
  3. 调用者与客户端交互
    public class Client {public static void main(String[] args) {Light light = new Light();Command cmdOn = new LightOnCommand(light);RemoteControl control = new RemoteControl();control.setCommand(cmdOn);control.pressButton(); // 输出:灯已开启}
    }
    
    结果:调用者与接收者完全解耦,支持灵活替换命令。

四、高级应用场景

  1. 撤销与重做(Undo/Redo)
    通过维护命令历史栈实现操作回滚。例如文本编辑器的撤销功能:
    class Editor {private String text;public void insert(String content) { /* 实现 */ }public void delete(String content) { /* 实现 */ }
    }
    class InsertCommand implements Command {private Editor receiver;private String content;public void execute() { receiver.insert(content); }public void undo() { receiver.delete(content); }
    }
    
  2. 宏命令(Macro Command)
    将多个命令组合为一个复合命令,实现批量操作:
    class MacroCommand implements Command {private List commands = new ArrayList<>();public void add(Command cmd) { commands.add(cmd); }public void execute() { commands.forEach(Command::execute); }
    }
    
  3. 异步任务队列
    结合线程池处理异步请求,提升系统吞吐量:
    class CommandQueue {private BlockingQueue queue = new LinkedBlockingQueue<>();public void addCommand(Command cmd) { queue.put(cmd); }public void process() { queue.forEach(cmd -> new Thread(cmd::execute).start()); }
    }
    

五、优缺点分析

优点缺点
解耦请求发送者与接收者,提升系统灵活性可能导致类爆炸问题(每个操作需独立命令类)
支持撤销、重做及事务管理,增强用户体验增加系统复杂度,需额外维护命令对象
符合开闭原则,扩展性强过度设计风险,简单场景可能不必要

六、适用场景

  1. GUI事件处理:如按钮点击、菜单操作。
  2. 事务性操作:数据库事务的提交与回滚。
  3. 日志与审计:记录操作历史以便恢复。
  4. 异步任务调度:如消息队列中的任务处理。

七、与其他模式的对比

  • 策略模式:关注算法替换,而命令模式关注请求封装。
  • 观察者模式:通过订阅-发布解耦,命令模式通过对象化请求解耦。
  • 责任链模式:请求逐级传递,命令模式明确单一行执行路径。

总结

命令模式通过对象化请求实现了高度解耦与灵活控制,是构建可扩展系统的利器。其核心价值在于将操作抽象为对象,支持复杂功能(如撤销、异步队列)的同时降低系统耦合度。实际应用中需根据场景权衡复杂性,避免滥用。

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

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

相关文章

大数据领域开山鼻祖组件Hadoop核心架构设计

一、Hadoop的整体架构 Hadoop是一个专为大数据设计的架构解决方案&#xff0c;历经多年开发演进&#xff0c;已逐渐发展成为一个庞大且复杂的系统。其内部工作机制融合了分布式理论与具体工程开发的精髓&#xff0c;构成了一个整体架构。 Hadoop最朴素的原理在于&#xff0c;它…

OneCode3.0 VFS分布式文件管理API速查手册

&#x1f4da; 前言&#xff1a;OneCode 3.0微内核引擎架构解析 在云原生与分布式系统日益普及的今天&#xff0c;文件管理系统面临着前所未有的挑战——海量数据存储、跨节点协同、多租户隔离以及弹性扩展等需求推动着传统文件系统向分布式架构演进。OneCode 3.0作为新一代企业…

UI前端与数字孪生结合实践探索:智慧物流的仓储自动化管理系统

hello宝子们...我们是艾斯视觉擅长ui设计、前端开发、数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩!一、引言&#xff1a;传统仓储的 “效率黑洞” 与数字孪生的破局当仓库管理员在数万平的库房中…

使用layui的前端框架过程中,无法加载css和js怎么办?

这使用layui的前端框架过程中&#xff0c;无法加载css和js怎么办&#xff1f;里写自定义目录标题已经按要求下载并解压到指定位置了&#xff0c;但是感觉就是无法加载文件后台提示如下&#xff1a;那就我清理缓存当再次观察html页面时&#xff0c;发现页面最开始有两个< htm…

gitlab+TortoiseGit克隆生成ppk方式

1、第一步 2、第二步3、第三步4、第四步&#xff0c;如何使用这个ppk就可以了

VSCode中使用容器及容器编排docker-compose

前面笔者写了一篇博文&#xff1a;使用容器编排对go项目进行部署、调试&#xff0c;介绍了在Goland中如何使用容器&#xff0c;由于Goland的容器配置是可视化的&#xff0c;使用起来非常方便&#xff0c;VSCode中也有一个容器插件&#xff0c;但是笔者一直未使用过&#xff0c;…

深度学习入门:让神经网络变得“深不可测“⚡(二)

深度学习入门&#xff1a;让神经网络变得"深不可测" &#x1f9e0;⚡ 系列课程第二弹&#xff1a;深度学习的奇妙世界 前言&#xff1a;从浅到深的华丽转身 哈喽&#xff0c;各位AI探险家&#xff01;&#x1f44b; 欢迎回到我们的"让机器变聪明"系列课…

硅基计划2.0 学习总结 捌 异常与常用工具类

文章目录一、异常1. 防御性编程2. throw关键字3. throws关键字4. 捕获5. finally关键字二、自定义异常类三、常用工具类1. Date以及相关的类1. 创建时间&#xff08;基本弃用&#xff09;2. 捕获系统时间3. 获取当前年月日时分秒4. 日期加减5. 根据字符串创建日期6. 根据当前时…

2025-7-14-C++ 学习 排序(2)

文章目录2025-7-14-C 学习 排序&#xff08;2&#xff09;P1059 [NOIP 2006 普及组] 明明的随机数题目描述输入格式输出格式输入输出样例 #1输入 #1输出 #1说明/提示提交代码P1093 [NOIP 2007 普及组] 奖学金题目背景题目描述输入格式输出格式输入输出样例 #1输入 #1输出 #1输入…

微信131~140

1.在组件中使用store对象的数据 // 要想使用store中的数据以及方法 // 需要从 mobx-miniprogram-bindings 方法将 ComponentWithStore 方法 import { ComponentWithStore } from mobx-miniprogram-bindings // 导入store对象 import { numStore } from ../../../stores/numstor…

微美全息借区块链与DRL算法打造资源管理协同架构,达成边缘计算与区块链动态适配

在当今数字化浪潮汹涌的时代&#xff0c;边缘计算与区块链技术正逐步成为驱动技术革新与业务转型升级的核心动力。当这两项前沿技术相互融合&#xff0c;一个兼具高效性与安全性的任务处理系统便得以构建。为了充分挖掘边缘计算系统的性能潜力&#xff0c;避免任务卸载过程中的…

属性绑定

简写模式二.为什么要这样做布尔型attribute动态绑定多个值

链表算法之【获取链表开始入环的节点】

目录 LeetCode-142题 LeetCode-142题 给定一个链表的头节点head&#xff0c;返回链表开始入环的第一个节点&#xff0c;如果链表无环&#xff0c;则返回null class Solution {public ListNode detectCycle(ListNode head) {// checkif (head null || head.next null)retur…

【网络编程】KCP——可靠的 UDP 传输协议——的知识汇总

文章目录前言UDP 协议UDP 的关键指标/特性UDP 的典型应用场景KCP 协议的基础KCP 的构造KCP 协议特性KCP 的可靠传输机制——ARQ三种 ARQ 机制对比KCP 的选择性重传一、基础机制&#xff1a;选择性重传&#xff08;SR&#xff09;二、KCP 对 SR 的增强策略KCP 的激进重传策略——…

量子计算新突破!阿里“太章3.0”实现512量子比特模拟(2025中国量子算力巅峰)

​​摘要​​2025年量子计算竞争进入​​实用化临界点​​&#xff0c;阿里达摩院发布“太章3.0”量子模拟器&#xff0c;在全球首次实现​​512量子比特全振幅模拟​​&#xff0c;较谷歌Sycamore的53比特提升近10倍算力维度。本文深度解析三大技术突破&#xff1a;​​张量网…

DOM事件绑定时机:解决脚本提前加载导致的绑定失败

引言&#xff1a;一个让无数新手抓狂的常见错误在JavaScript开发中&#xff0c;尤其是在前端领域&#xff0c;有一个让无数新手抓狂的问题&#xff1a;明明写了事件监听代码&#xff0c;点击按钮却没有任何反应&#xff01;更令人困惑的是&#xff0c;代码逻辑看起来完全正确&a…

游戏框架笔记

游戏的数据有哪些类型无非是只读数据&#xff08;各种道具配表里的数据&#xff09;和可读可写数据&#xff08;玩家属性、拥有的物品&#xff09;。游戏框架需要哪些管理器用户数据管理器负责找到数据持久化文件&#xff0c;从中读取指定用户的数据&#xff0c;包括玩家的设置…

【C语言进阶】指针面试题详解(2)

上一期内容&#xff0c;大多数的解题思路写在代码中&#xff0c;没有写在正文中&#xff0c;这就导致系统判断文章质量不高&#xff0c;没有什么数据&#xff0c;这一期将思路写在正文中。注意&#xff1a;运行环境是x86 1.题目1思路&#xff1a;&a是取到了整个数组的地址&…

一文读懂现代卷积神经网络—稠密连接网络(DenseNet)

目录 什么是 DenseNet&#xff1f; 稠密块&#xff08;Dense Block&#xff09;详解 一、稠密块的核心思想 二、稠密块的结构组成 1. 卷积单元&#xff08;的结构&#xff09; 2. 密集连接的具体方式 3. 关键参数&#xff1a;增长率&#xff08;Growth Rate, k&#xff0…

关于僵尸进程

深入理解僵尸进程&#xff1a;成因、危害与解决方案 进程终止的条件 我们先了解一下进程销毁的条件&#xff1a; 调用了exit函数在main函数中执行了return语句 无论采用哪种方式&#xff0c;都会有一个返回值&#xff0c;这个返回值由操作系统传递给该进程的父进程。操作系统不…