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

发布于:2025-02-11 ⋅ 阅读:(30) ⋅ 点赞:(0)

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. 任务队列系统:将请求封装为命令对象进行异步处理。

八、总结

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

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