Command 设计模式将请求封装为对象,从而允许您使用不同的请求、队列或日志请求参数化客户端,并支持可撤消的操作。
UML类图

C# 中的结构代码
#
此结构代码演示了 Command 模式,该模式将请求存储为允许客户端执行或播放请求的对象。
- using System;
- namespace Command.Structural
- {
- /// <summary>
- /// Command Design Pattern
- /// </summary>
- public class Program
- public static void Main(string[] args)
- // Create receiver, command, and invoker
- Receiver receiver = new Receiver();
- Command command = new ConcreteCommand(receiver);
- Invoker invoker = new Invoker();
- // Set and execute command
- invoker.SetCommand(command);
- invoker.ExecuteCommand();
- // Wait for user
- Console.ReadKey();
- }
- /// The 'Command' abstract class
- public abstract class Command
- protected Receiver receiver;
- // Constructor
- public Command(Receiver receiver)
- this.receiver = receiver;
- public abstract void Execute();
- /// The 'ConcreteCommand' class
- public class ConcreteCommand : Command
- public ConcreteCommand(Receiver receiver) :
- base(receiver)
- public override void Execute()
- receiver.Action();
- /// The 'Receiver' class
- public class Receiver
- public void Action()
- Console.WriteLine("Called Receiver.Action()");
- /// The 'Invoker' class
- public class Invoker
- Command command;
- public void SetCommand(Command command)
- this.command = command;
- public void ExecuteCommand()
- command.Execute();
C# 中的实际代码
此实际代码演示了在简单计算器中使用的命令模式,该计算器具有无限数量的撤消和重做。请注意,在 C# 中,单词"operator"是一个关键字。在前缀为前缀"@"允许将其用作标识符。
- using System.Collections.Generic;
- namespace Command.RealWorld
- // Create user and let her compute
- User user = new User();
- // User presses calculator buttons
- user.Compute('+', 100);
- user.Compute('-', 50);
- user.Compute('*', 10);
- user.Compute('/', 2);
- // Undo 4 commands
- user.Undo(4);
- // Redo 3 commands
- user.Redo(3);
- public abstract void UnExecute();
- public class CalculatorCommand : Command
- char @operator;
- int operand;
- Calculator calculator;
- public CalculatorCommand(Calculator calculator,
- char @operator, int operand)
- this.calculator = calculator;
- this.@operator = @operator;
- this.operand = operand;
- // Gets operator
- public char Operator
- set { @operator = value; }
- // Get operand
- public int Operand
- set { operand = value; }
- // Execute new command
- calculator.Operation(@operator, operand);
- // Unexecute last command
- public override void UnExecute()
- calculator.Operation(Undo(@operator), operand);
- // Returns opposite operator for given operator
- private char Undo(char @operator)
- switch (@operator)
- case '+': return '-';
- case '-': return '+';
- case '*': return '/';
- case '/': return '*';
- default:
- throw new
- ArgumentException("@operator");
- public class Calculator
- int curr = 0;
- public void Operation(char @operator, int operand)
- case '+': curr += operand; break;
- case '-': curr -= operand; break;
- case '*': curr *= operand; break;
- case '/': curr /= operand; break;
- Console.WriteLine(
- "Current value = {0,3} (following {1} {2})",
- curr, @operator, operand);
- public class User
- // Initializers
- Calculator calculator = new Calculator();
- List<Command> commands = new List<Command>();
- int current = 0;
- public void Redo(int levels)
- Console.WriteLine("\n---- Redo {0} levels ", levels);
- // Perform redo operations
- for (int i = 0; i < levels; i++)
- if (current < commands.Count - 1)
- Command command = commands[current++];
- public void Undo(int levels)
- Console.WriteLine("\n---- Undo {0} levels ", levels);
- // Perform undo operations
- if (current > 0)
- Command command = commands[--current] as Command;
- command.UnExecute();
- public void Compute(char @operator, int operand)
- // Create command operation and execute it
- Command command = new CalculatorCommand(calculator, @operator, operand);
- // Add command to undo list
- commands.Add(command);
- current++;