【C#设计模式(15)——命令模式(Command Pattern)】
前言
命令模式的关键通过将请求封装成一个对象,使命令的发送者和接收者解耦。这种方式能更方便地添加新的命令,如执行命令的排队、延迟、撤销和重做等操作。
代码
#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