命令模式將請求封裝為物件,使您能用不同請求參數化用戶端、將請求佇列化或記錄日誌、支援可撤銷操作。屬於行為型模式。
需要支援撤銷或恢復操作時。
Execute()Execute() 呼叫 Receiver.Action()Execute()
abstract class Command { protected Receiver receiver; public Command(Receiver r) { receiver = r; } public abstract void Execute(); }
class ConcreteCommand : Command {
public ConcreteCommand(Receiver r) : base(r) { }
public override void Execute() => receiver.Action();
}
class Receiver { public void Action() => Console.WriteLine("Called Receiver.Action()"); }
class Invoker { Command _cmd; public void SetCommand(Command c) => _cmd = c; public void ExecuteCommand() => _cmd.Execute(); }
// Client
static void Main() {
var invoker = new Invoker();
invoker.SetCommand(new ConcreteCommand(new Receiver()));
invoker.ExecuteCommand();
}
場景:四則運算,支援撤銷與重做。
Command:抽象類別,Execute()、UnExecute()CalculatorCommand:持有 Calculator、運算子、運算元,Execute() 呼叫 Calculator.Operation(),UnExecute() 呼叫反向運算子Calculator:接收者,Operation(op, val) 執行 + - * /User:調用者,維護命令清單 _commands 與游標 _current,Compute() 建立命令並執行,Undo()/Redo() 移動游標呼叫 UnExecute()/Execute()
// CalculatorCommand 關鍵
public override void Execute() => _calculator.Operation(_operator, _operand);
public override void UnExecute() => _calculator.Operation(Undo(_operator), _operand);
private char Undo(char op) => op switch { '+' => '-', '-' => '+', '*' => '/', '/' => '*', _ => throw new ArgumentException() };
// User 關鍵
public void Compute(char op, int val) {
var cmd = new CalculatorCommand(_calculator, op, val);
cmd.Execute(); _commands.Add(cmd); _current++;
}
public void Undo(int levels) { for (int i=0;i0) _commands[--_current].UnExecute(); }
public void Redo(int levels) { for (int i=0;i
命令模式將操作物件化,原生支援撤銷/重做、巨集記錄、佇列執行,是編輯器、交易系統、GUI 框架的核心模式之一。