【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

运行结果

相关推荐
ghost1431 小时前
C#学习第22天:网络编程
开发语言·学习·c#
范纹杉想快点毕业1 小时前
以项目的方式学QT开发(三)——超详细讲解(120000多字详细讲解,涵盖qt大量知识)逐步更新!
c语言·开发语言·c++·qt·mysql·算法·命令模式
神仙别闹2 小时前
基于C#实现中央定位服务器的 P2P 网络聊天系统
服务器·网络·c#
阿蒙Amon2 小时前
DevExpress&WinForms-TreeList-数据绑定
c#·devexpress·winforms
bicijinlian4 小时前
.Net HttpClient 使用代理功能
c#·.net·httpclient·.net httpclient·httpclient 代理
君鼎7 小时前
C++设计模式——单例模式
c++·单例模式·设计模式
敲代码的 蜡笔小新9 小时前
【行为型之中介者模式】游戏开发实战——Unity复杂系统协调与通信架构的核心秘诀
unity·设计模式·c#·中介者模式
令狐前生9 小时前
设计模式学习整理
学习·设计模式
程序猿多布9 小时前
使用Visual Studio将C#程序发布为.exe文件
c#·visual studio
老衲有点帅10 小时前
C#多线程Thread
开发语言·c#