【C#设计模式(15)——命令模式(Command Pattern)】

前言

命令模式的关键通过将请求封装成一个对象,使命令的发送者和接收者解耦。这种方式能更方便地添加新的命令,如执行命令的排队、延迟、撤销和重做等操作。

代码

csharp 复制代码
#region 基础的命令模式
//命令(抽象类)
public abstract class Command
{
    public abstract void Execute();
}
//发送命令
public class SendCommand : Command
{
    private Receiver receiver;
    public SendCommand(Receiver receiver)
    {
        this.receiver = receiver;
    }
    public override void Execute()
    {
        receiver.Execute();
    }
}
//接收命令
public class Receiver
{
    public void Execute()
    {
        Console.WriteLine("receiver execute the command...");
    }
}
//调用者命令
public class Invoker
{
    private Command command;
    public void SetCommand(Command command)
    {
        this.command = command;
    }
    public void ExecuteCommand()
    {
        command.Execute();
    }
}
#endregion

#region 添加新的命令模式
//新命令
public class NewCommand : Command
{
    private NewReceiver newReceiver;
    public NewCommand(NewReceiver newReceiver)
    {
        this.newReceiver = newReceiver;
    }
    public override void Execute()
    {
        newReceiver.Execute();
    }
}
//使用新接收者
public class NewReceiver
{
    public void Execute()
    {
        Console.WriteLine("new reveiver execute the newCommand...");
    }
}

#endregion

#region 命令的请求的排队和延迟执行
//命令执行者
public class CommandInvoker
{
    private List<Command> commandQueue = new List<Command>();

    public void AddCommand(Command command)
    {
        commandQueue.Add(command);
    }
    public void ExecuteCommands()
    {
        foreach (Command command in commandQueue)
        {
            command.Execute();
        }
        commandQueue.Clear();
    }

    public void DelayExecute(Command command,int delay)
    {
        Console.WriteLine($"等待开始....时间:{delay}ms");
        new Thread(() =>
        {
            Console.WriteLine($"延时执行开始==>");
            Thread.Sleep(delay);
            command.Execute();
            Console.WriteLine($"finish time:{Environment.NewLine}{DateTime.Now.ToString("HH:mm:ss fff")}");
            Console.WriteLine($"==>延时执行完毕...");
        }).Start();
        
    }
}
#endregion

#region 命令撤销和重做操作
public interface ICommand
{
    void Execute();
    void Undo(); 
}

public class HistoryCommand : ICommand
{
    private HistoryReceiver historyReceiver;
    public HistoryCommand(HistoryReceiver historyReceiver)
    {
        this.historyReceiver = historyReceiver;
    }
    public void Execute()
    {
        historyReceiver.Execute();
    }
    public void Undo()
    {
        historyReceiver.UndoExecute();
    }
}

public class HistoryReceiver
{
    public void Execute()
    {
        Console.WriteLine("history receiver executes the command...");
    }
    public void UndoExecute()
    {
        Console.WriteLine("history receiver undoes the command...");
    }
}
public class HistoryInvoker
{
    private Stack<ICommand> commandStack = new Stack<ICommand>();

    public void ExecuteCommand(ICommand command)
    {
        command.Execute();
        commandStack.Push(command);
    }

    public void Undo()
    {
        if (commandStack.Count > 0)
        {
            ICommand command = commandStack.Pop();
            Console.WriteLine("command Undo");
            command.Undo();
        }
        else
        {

            Console.WriteLine("No commands to undo.");
        }
    }
    public void Redo()
    {
        if (commandStack.Count>0)
        {
            ICommand command = commandStack.Peek();
            Console.WriteLine("command Redo");
            command.Execute();
        }
        else
        {
            Console.WriteLine("No commands to redo.");
        }
    }
}


 /*
  * 行为型模式:Behavioral Pattern
  * 命令模型:Command Pattern
  */
 internal class Program
 {
     static void Main(string[] args)
     {
         //命令模式:简单实现
         Receiver receiver = new Receiver();
         Command sendCommand = new SendCommand(receiver);
         Invoker invoker = new Invoker();
         invoker.SetCommand(sendCommand);
         invoker.ExecuteCommand();

         Console.WriteLine("添加新命令------------------------------------");
         // 命令模式:添加新命令
         NewReceiver newReceiver = new NewReceiver();
         Command newCommand = new NewCommand(newReceiver);

         invoker.SetCommand(newCommand);
         invoker.ExecuteCommand();

         Console.WriteLine("请求队列------------------------------------");
         //命令模式:请求队列
         Receiver receiver1 = new Receiver();
         Command command1 = new SendCommand(receiver1);
         Command command2 = new SendCommand(receiver1);
         CommandInvoker commandInvoker = new CommandInvoker();
         commandInvoker.AddCommand(command1);
         commandInvoker.AddCommand(command2);
         commandInvoker.ExecuteCommands();

         Console.WriteLine("延时执行------------------------------------");
         Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss fff")}");
         //命令模式:延时执行
         commandInvoker.DelayExecute(command1,1000);

         Console.WriteLine("准备撤销重做------------------------------------");
         HistoryReceiver historyReceiver = new HistoryReceiver();
         ICommand command3 = new HistoryCommand(historyReceiver);
         ICommand command4 = new HistoryCommand(historyReceiver);

         HistoryInvoker historyInvoker = new HistoryInvoker();
         historyInvoker.ExecuteCommand(command3);
         historyInvoker.ExecuteCommand(command4);
         Console.WriteLine("执行撤销重做------------------------------------");
         //撤销最后一个命令
         historyInvoker.Undo();
         historyInvoker.Undo();
         //重做最后一个撤销命令
         historyInvoker.Redo();
         Console.WriteLine("END------------------------------------");
         Console.ReadLine();
     }
 }
#endregion

运行结果

相关推荐
缺点内向几秒前
C#: 告别繁琐!轻松移除Word文档中的文本与图片水印
c#·自动化·word·.net
喵叔哟40 分钟前
06-ASPNETCore-WebAPI开发
服务器·后端·c#
2501_930707781 小时前
使用 C# .NET 从 PowerPoint 演示文稿中提取背景图片
c#·powerpoint·.net
初级代码游戏1 小时前
套路化编程 C# winform 自适应缩放布局
开发语言·c#·winform·自动布局·自动缩放
大空大地20263 小时前
流程控制语句--switch多分支语句使用、while循环语句的使用、do...while语句、for循环
c#
苏渡苇4 小时前
优雅应对异常,从“try-catch堆砌”到“设计驱动”
java·后端·设计模式·学习方法·责任链模式
kylezhao20194 小时前
C#序列化与反序列化详细讲解与应用
c#
JQLvopkk4 小时前
C# 实践AI :Visual Studio + VSCode 组合方案
人工智能·c#·visual studio
故事不长丨5 小时前
C#线程同步:lock、Monitor、Mutex原理+用法+实战全解析
开发语言·算法·c#
kingwebo'sZone5 小时前
C#使用Aspose.Words把 word转成图片
前端·c#·word