Command
Encapsulates a request as an object, allowing parameterization, queuing, logging, and undo operations.
Context
You need to implement undo/redo, queue tasks, execute offline, or audit user actions.
Problem
A direct method cannot be reversed, logged, or queued.
Solution
Each action becomes an ICommand object with Execute() and optionally Undo().
#Example in C#
public interface ICommand { void Execute(); void Undo(); }
public class AddTextCommand : ICommand
{
private readonly Document _doc; private readonly string _text;
public AddTextCommand(Document d, string t) { _doc = d; _text = t; }
public void Execute() => _doc.Append(_text);
public void Undo() => _doc.RemoveLast(_text.Length);
}
public class CommandHistory
{
private readonly Stack<ICommand> _stack = new();
public void Run(ICommand c) { c.Execute(); _stack.Push(c); }
public void Undo() { if (_stack.TryPop(out var c)) c.Undo(); }
}When NOT to use it
When you don't need undo/queue/log: adds boilerplate without value.
Tradeoffs
| Pro | Con |
|---|---|
| Enables undo, queue, audit, replay | One class per action |
| Decouples sender and receiver | More memory if history is stored |
#behavioral #gof #undo