Command Pattern: Actions as Objects
design-patternsbehavioralcommand

Intent
Command encapsulates a request as an object, allowing you to parameterize clients with different requests, queue or log requests, and support reversible operations (undo/redo).
The Problem
Imagine a text editor. Without Command, undo code would be a mess:
// Without pattern: global state and scattered logic
let previousContent: string;
function bold() {
previousContent = content;
content = `<b>${content}</b>`;
}
function undo() {
content = previousContent; // What about multiple undos?
}The Solution: Command
classDiagram
class Command {
<<interface>>
+execute(): void
+undo(): void
}
class Invoker {
-history: Command[]
+executeCommand(cmd)
+undoLast()
}
Command <|.. ConcreteCommand
Invoker --> CommandTypeScript Implementation
interface Command {
execute(): void;
undo(): void;
}
class InsertTextCommand implements Command {
constructor(
private document: TextDocument,
private position: number,
private text: string
) {}
execute(): void {
this.document.insertAt(this.position, this.text);
}
undo(): void {
this.document.deleteRange(this.position, this.position + this.text.length);
}
}
class TextEditor {
private history: Command[] = [];
private redoStack: Command[] = [];
executeCommand(cmd: Command): void {
cmd.execute();
this.history.push(cmd);
this.redoStack = [];
}
undo(): boolean {
const cmd = this.history.pop();
if (!cmd) return false;
cmd.undo();
this.redoStack.push(cmd);
return true;
}
redo(): boolean {
const cmd = this.redoStack.pop();
if (!cmd) return false;
cmd.execute();
this.history.push(cmd);
return true;
}
}When to Use
| Situation | Recommendation |
|---|---|
| Undo/Redo operations | ✅ Recommended |
| Task queues | ✅ Recommended |
| Transactions | ✅ Recommended |
| Simple operations without history | ❌ Overkill |
Conclusion
Command transforms operations into first-class objects, enabling undo, queues, and composition.