patterntypescriptTip
Command Pattern: Encapsulate Operations as Objects for Undo/Queue
Viewed 0 times
command patternbehavioral patternundo redocommand historyoperation queueencapsulate action
Problem
You need to parameterize actions, support undo/redo, queue operations for later execution, or log operations for audit. A direct method call cannot be stored, reversed, or queued.
Solution
Encapsulate each operation as a command object implementing
execute() and optionally undo(). A command history stack enables undo/redo.interface Command {
execute(): void;
undo(): void;
}
class TextEditor {
private text = '';
getText() { return this.text; }
insert(at: number, str: string) { this.text = this.text.slice(0, at) + str + this.text.slice(at); }
delete(at: number, length: number) { this.text = this.text.slice(0, at) + this.text.slice(at + length); }
}
class InsertCommand implements Command {
constructor(private editor: TextEditor, private at: number, private text: string) {}
execute() { this.editor.insert(this.at, this.text); }
undo() { this.editor.delete(this.at, this.text.length); }
}
class CommandHistory {
private history: Command[] = [];
execute(cmd: Command) { cmd.execute(); this.history.push(cmd); }
undo() { this.history.pop()?.undo(); }
}
const editor = new TextEditor();
const history = new CommandHistory();
history.execute(new InsertCommand(editor, 0, 'Hello'));
history.execute(new InsertCommand(editor, 5, ' World'));
history.undo(); // removes ' World'Why
Command transforms imperative calls into data. This unlocks logging, replay, deferred execution, and undo — capabilities impossible with bare function calls stored nowhere.
Gotchas
- Undo state must be captured at command creation time. If the editor state mutates before undo is called and you rely on current state, undo will be incorrect.
- Macro commands (composite commands) are easy to implement: a MacroCommand holds a list and delegates execute/undo to each child.
- Command objects can grow large if they hold references to large objects. Consider storing diffs rather than full snapshots.
Revisions (0)
No revisions yet.