Command
Overview
Encapsulate a request as an object, allowing parameterization, queuing, and undo support.
When to use
- You need undo/redo.
- You want to queue or log operations.
- You want the invoker to stay decoupled from the receiver that does the real work.
Java example
interface Command {
void execute();
}
class Editor {
void save() {
System.out.println("saved");
}
}
class SaveCommand implements Command {
private final Editor editor;
SaveCommand(Editor editor) {
this.editor = editor;
}
public void execute() {
editor.save();
}
}
class Invoker {
void run(Command cmd) {
cmd.execute();
}
}
TypeScript example
interface Command {
execute(): void;
}
class Editor {
save(): void {
console.log('saved');
}
}
class SaveCommand implements Command {
constructor(private editor: Editor) {}
execute(): void {
this.editor.save();
}
}
class Invoker {
run(cmd: Command): void {
cmd.execute();
}
}
Pros and cons
Pros:
- Supports undo/redo, queuing, and logging.
- Decouples invoker from receiver.
Cons:
- Many small classes.
- Indirection can be heavy for simple actions.
Common pitfalls
- Not capturing all necessary state for undo.
- Creating commands for trivial operations.