Lesson 18 / 25
Command
Actions as objects: undo, redo and queues.
Encapsulate a request
Intent: turn a request into an object that holds everything needed to perform it, so requests can be queued, logged, retried, scheduled or undone. Text editors and design tools implement undo/redo with commands that know how to execute and undo themselves, kept on two stacks. Job queues serialise commands ("resize image 42") so a worker can run them later. Modern alternatives: a closure is a lightweight command when you only need "run later", and a plain serialisable object ({ type: 'resizeImage', imageId: 42 }) is the usual command format for queues and for reducers in state libraries such as Redux. Avoid full command classes when nothing needs to be stored, undone or replayed.
Undo and redo in an editor
Each command knows how to apply and revert itself.
interface Command {
execute(): void;
undo(): void;
}
class InsertText implements Command {
constructor(private doc: TextDocument, private pos: number, private text: string) {}
execute() { this.doc.insert(this.pos, this.text); }
undo() { this.doc.delete(this.pos, this.text.length); }
}
class History {
private done: Command[] = [];
private undone: Command[] = [];
run(cmd: Command) {
cmd.execute();
this.done.push(cmd);
this.undone = []; // a new action clears the redo stack
}
undo() {
const cmd = this.done.pop();
if (cmd) { cmd.undo(); this.undone.push(cmd); }
}
redo() {
const cmd = this.undone.pop();
if (cmd) { cmd.execute(); this.done.push(cmd); }
}
}
history.run(new InsertText(doc, 0, 'Hello'));
history.undo();
history.redo();A restaurant order ticket
The waiter writes your order on a ticket instead of cooking it. The ticket can wait in a queue, be handed to any cook, or be torn up if you change your mind.
Quick check: Why does Command make undo possible?
- Each action is an object that stores what is needed to execute and reverse it
- It deletes old data automatically
- It uses a Singleton history
- It prevents actions from running
Answer
Each action is an object that stores what is needed to execute and reverse it — Encapsulated requests can be stored and reversed.