C# 设计模式(行为型模式):命令模式(专注于撤销重做)

news2025/1/7 22:06:30

C# 设计模式(行为型模式):命令模式 (Command Pattern)


一、什么是命令模式?

命令模式(Command Pattern)是一种行为型设计模式,它将请求封装成一个对象,从而使你可以用不同的请求、队列或者日志来参数化对象。此模式使得请求的发送者和接受者完全解耦。

在命令模式中,一个命令就是一个独立的对象,包含了执行请求所需的所有信息。这种模式非常适合需要撤销/重做操作或事务管理的场景。


二、模式结构
  1. Command(抽象命令类):声明执行操作的接口。
  2. ConcreteCommand(具体命令类):实现命令接口,绑定一个接收者对象,调用接收者的相应操作。
  3. Invoker(调用者):调用命令对象执行具体请求。
  4. Receiver(接收者):执行命令请求的具体对象。
  5. Client(客户端):创建命令对象并设置接收者和调用者。

三、适用场景
  1. 撤销/重做操作:如文本编辑器的撤销和重做功能。
  2. 任务队列:将请求放入队列以便稍后执行。
  3. 事务系统:需要记录日志并支持操作回滚。

四、C# 实现案例
1. 场景描述

模拟一个智能家居系统,支持打开和关闭灯的功能,同时能够支持撤销上一个操作。

2. 实现代码
using System;
using System.Collections.Generic;

namespace CommandPatternExample
{
    // 命令接口
    public interface ICommand
    {
        void Execute();
        void Undo();
    }

    // 具体命令:打开灯
    public class LightOnCommand : ICommand
    {
        private Light _light;

        public LightOnCommand(Light light)
        {
            _light = light;
        }

        public void Execute()
        {
            _light.On();
        }

        public void Undo()
        {
            _light.Off();
        }
    }

    // 具体命令:关闭灯
    public class LightOffCommand : ICommand
    {
        private Light _light;

        public LightOffCommand(Light light)
        {
            _light = light;
        }

        public void Execute()
        {
            _light.Off();
        }

        public void Undo()
        {
            _light.On();
        }
    }

    // 接收者:灯
    public class Light
    {
        public void On()
        {
            Console.WriteLine("灯已打开");
        }

        public void Off()
        {
            Console.WriteLine("灯已关闭");
        }
    }

    // 调用者
    public class RemoteControl
    {
        private ICommand _command;
        private Stack<ICommand> _commandHistory = new Stack<ICommand>();

        public void SetCommand(ICommand command)
        {
            _command = command;
        }

        public void PressButton()
        {
            _command.Execute();
            _commandHistory.Push(_command);
        }

        public void PressUndo()
        {
            if (_commandHistory.Count > 0)
            {
                var lastCommand = _commandHistory.Pop();
                lastCommand.Undo();
            }
            else
            {
                Console.WriteLine("没有可撤销的操作");
            }
        }
    }

    // 客户端
    class Program
    {
        static void Main(string[] args)
        {
            // 创建接收者
            var light = new Light();

            // 创建命令
            var lightOn = new LightOnCommand(light);
            var lightOff = new LightOffCommand(light);

            // 设置调用者
            var remote = new RemoteControl();

            // 打开灯
            remote.SetCommand(lightOn);
            remote.PressButton();

            // 关闭灯
            remote.SetCommand(lightOff);
            remote.PressButton();

            // 撤销操作
            remote.PressUndo();
            remote.PressUndo();
        }
    }
}

五、运行结果

执行上述代码,输出如下:

灯已打开
灯已关闭
灯已打开
灯已关闭

六、优缺点分析
优点
  1. 解耦发送者和接收者:命令模式将调用者与接收者隔离。
  2. 支持撤销和重做:通过记录命令历史,可以轻松实现撤销和重做操作。
  3. 扩展性强:增加新命令时,只需实现命令接口,原有代码无需修改。
缺点
  1. 类数量增加:每个命令都需要一个具体命令类,可能导致类数量过多。
  2. 实现复杂:如果命令链条较长或逻辑复杂,会增加代码的维护难度。

七、实际应用场景
  1. 文本编辑器:实现撤销和重做功能。
  2. 智能家居系统:管理多个设备的操作。
  3. 游戏开发:管理用户的操作记录。
  4. 任务队列系统:将请求封装为命令对象进行异步处理。

八、总结

命令模式是一种功能强大且灵活的设计模式,适合需要将请求与实际执行解耦的场景。通过命令模式,可以轻松实现操作的撤销、重做以及请求的排队处理。如果你的应用程序需要这些功能,不妨试试命令模式!

希望本文能帮助你更好地理解命令模式。如果你有任何问题或建议,欢迎在评论区留言! 😊

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

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

相关文章

Anaconda安装(2024最新版)

安装新的anaconda需要卸载干净上一个版本的anaconda&#xff0c;不然可能会在新版本安装过程或者后续使用过程中出错&#xff0c;完全卸载干净anaconda的方法&#xff0c;可以参考我的博客&#xff01; 第一步&#xff1a;下载anaconda安装包 官网&#xff1a;Anaconda | The O…

docker中使用Volume完成数据共享

情景概述 在一个docker中&#xff0c;部署两个MySQL容器&#xff0c;假如它们的数据都存储在自己容器内部的data目录中。这样的存储方式会有以下问题&#xff1a; 1.无法保证两个MySQL容器中的数据同步。 2.容器删除后&#xff0c;数据就会丢失。 基于以上问题&#xff0c;容…

Mac软件介绍之录屏软件Filmage Screen

软件介绍 Filmage Screen 是一款专业的视频录制和编辑软件&#xff0c;适用于 Mac 系统 可以选择4k 60fps&#xff0c;可以选择录制电脑屏幕&#xff0c;摄像头录制&#xff0c;可以选择区域录制。同时也支持&#xff0c;简单的视频剪辑。 可以同时录制电脑麦克风声音 标准…

【Redis经典面试题七】Redis的事务机制是怎样的?

目录 一、Redis的事务机制 二、什么是Redis的Pipeline&#xff1f;和事务有什么区别&#xff1f; 三、Redis的事务和Lua之间有哪些区别&#xff1f; 3.1 原子性保证 3.2 交互次数 3.3 前后依赖 3.4 流程编排 四、为什么Lua脚本可以保证原子性&#xff1f; 五、为什么R…

【C++面向对象——群体类和群体数据的组织】实现含排序功能的数组类(头歌实践教学平台习题)【合集】

目录&#x1f60b; 任务描述 相关知识 1. 相关排序和查找算法的原理 2. C 类与成员函数的定义 3. 数组作为类的成员变量的处理 4. 函数参数传递与返回值处理 编程要求 测试说明 通关代码 测试结果 任务描述 本关任务&#xff1a; 将直接插入排序、直接选择排序、冒泡…

[开源]自动化定位建图系统

系统状态机&#xff1a; 效果展示&#xff1a; 1、 机器人建图定位系统-基础重定位&#xff0c;定位功能演示 2、 机器人建图定位系统-增量地图构建&#xff0c;手动回环检测演示 3、敬请期待… 开源链接&#xff1a; 1、多传感器融合里程计 https://gitee.com/li-wenhao-lw…

简单的jmeter数据请求学习

简单的jmeter数据请求学习 1.需求 我们的流程服务由原来的workflow-server调用wfms进行了优化&#xff0c;将wfms服务操作并入了workflow-server中&#xff0c;去除了原来的webservice服务调用形式&#xff0c;增加了并发处理&#xff0c;现在想测试模拟一下&#xff0c;在一…

conda/pip基本常用命令理解与整理

最近配置了两轮pytorch环境&#xff0c;由于要频繁用到各种conda和pip命令&#xff0c;所以再此整理一下。 文章目录 前言&#xff1a;conda虚拟环境总结与解读Conda和pip的理解区别和联系命令格式 conda环境命令查看创建和删除导出与导入激活和退出 包管理命令安装和删除文件批…

Maven 详细配置:Maven settings 配置文件的详细说明

Maven settings 配置文件是 Maven 环境的重要组成部分&#xff0c;它用于定义用户特定的配置信息和全局设置&#xff0c;例如本地仓库路径、远程仓库镜像、代理服务器以及认证信息等。settings 文件分为全局配置文件&#xff08;settings.xml&#xff09;和用户配置文件&#x…

Unity-Mirror网络框架-从入门到精通之Chat示例

文章目录 前言Chat聊天室Authentication授权ChatAuthenticatorChat示例中的授权流程聊天Chat最后 前言 在现代游戏开发中&#xff0c;网络功能日益成为提升游戏体验的关键组成部分。Mirror是一个用于Unity的开源网络框架&#xff0c;专为多人游戏开发设计。它使得开发者能够轻…

复杂园区网基本分支的构建

目录 1、各主机进行网络配置。2、交换机配置。3、配置路由交换&#xff0c;进行测试。4、配置路由器接口和静态路由&#xff0c;进行测试。5、最后测试任意两台主机通信情况 模拟环境链接 拓扑结构 说明&#xff1a; VLAN标签在上面的一定是GigabitEthernet接口的&#xff0c…

这是什么操作?强制迁移?GitLab 停止中国区用户访问

大家好&#xff0c;我是鸭鸭&#xff01; 全球知名代码托管平台 GitLab 发布通告&#xff0c;宣布不再为位于中国大陆、香港及澳门地区的用户提供访问服务&#xff0c;并且“贴心”建议&#xff0c;可以访问极狐 GitLab。 极狐 GitLab 是一家中外合资公司&#xff0c;宣称获得…

CDP集成Hudi实战-spark shell

[〇]关于本文 本文主要解释spark shell操作Hudi表的案例 软件版本Hudi1.0.0Hadoop Version3.1.1.7.3.1.0-197Hive Version3.1.3000.7.3.1.0-197Spark Version3.4.1.7.3.1.0-197CDP7.3.1 [一]使用Spark-shell 1-配置hudi Jar包 [rootcdp73-1 ~]# for i in $(seq 1 6); do s…

设计模式学习[15]---适配器模式

文章目录 前言1.引例2.适配器模式2.1 对象适配器2.2 类适配器 总结 前言 这个模式其实在日常生活中有点常见&#xff0c;比如我们的手机取消了 3.5 m m 3.5mm 3.5mm的接口&#xff0c;只留下了一个 T y p e − C Type-C Type−C的接口&#xff0c;但是我现在有一个 3.5 m m 3.…

数据挖掘——数据预处理

数据挖掘——数据预处理 数据预处理数据预处理 ——主要任务数据清洗如何处理丢失的数据如何处理噪声数据如何处理不一致数据 数据集成相关分析相关系数(也成为皮尔逊相关系数)协方差 数据规约降维法&#xff1a;PCA主成分分析降数据——抽样法数据压缩 数据预处理 数据预处理…

Unity-Mirror网络框架-从入门到精通之CCU示例

文章目录 前言什么是CCU&#xff1f;测试结果最后 前言 在现代游戏开发中&#xff0c;网络功能日益成为提升游戏体验的关键组成部分。Mirror是一个用于Unity的开源网络框架&#xff0c;专为多人游戏开发设计。它使得开发者能够轻松实现网络连接、数据同步和游戏状态管理。本文…

如何在 Ubuntu 22.04 上安装 Nagios 服务器教程

简介 在本教程中&#xff0c;我们将解释如何在 Ubuntu 22.04 上安装和配置 Nagios&#xff0c;使用 Apache 作为 Web 服务器&#xff0c;并通过 Let’s Encrypt Certbot 使用 SSL 证书进行保护。 Nagios 是一个强大的监控系统&#xff0c;它可以帮助组织在 IT 基础设施问题影…

大语言模型训练所需的最低显存,联邦大语言模型训练的传输优化技术

联邦大语言模型训练的传输优化技术 目录 联邦大语言模型训练的传输优化技术大语言模型训练所需的最低显存大语言模型训练所需的最低显存 基于模型微调、压缩和分布式并行处理的方法,介绍了相关开源模型及技术应用 核心创新点 多维度优化策略:综合运用基于模型微调、模型压缩和…

Javascript算法——贪心算法(一)

贪心算法详解&#xff08;JavaScript&#xff09;&#xff08;局部最优->全局最优&#xff09; 贪心算法&#xff08;Greedy Algorithm&#xff09;是一种在每一步选择中都采取当前状态下的最优选择&#xff08;局部最优&#xff09;的算法设计方法。通过局部最优解的累积&…

141.《mac m系列芯片安装mongodb详细教程》

文章目录 下载从官网下载安装包 下载后双击解压出文件夹安装文件名修改为 mongodb配置data存放位置和日志log的存放位置启动方式一方式二方式二:输入mongo报错以及解决办法 本人电脑 m2 pro,属于 arm 架构 下载 官网地址: mongodb官网 怎么查看自己电脑应该下载哪个版本,输入…