Skip to main content

🧩 Command Pattern

✅ Intent

  • Represent each user action as a command object that can be executed, undone, and redone
  • Encapsulate operations to enable flexible undo/redo and history tracking

✅ Motivation

  • Ideal for implementing Undo/Redo functionality in text editors, GUIs, and batch operations
  • Allows you to log, test, or replay operations individually

✅ When to Use

  • In systems like text editors, forms, batch processors, or GUI components
  • When you want to separate the "action" from the "receiver" and support reversible operations

✅ Code Example

// コマンドインターフェース
interface Command {
execute(): void;
undo(): void;
}

// 受信者(対象クラス)
class TextEditor {
private content = "";

add(text: string) {
this.content += text;
}

remove(length: number) {
this.content = this.content.slice(0, -length);
}

getContent(): string {
return this.content;
}
}

// コマンド実装
class TypeCommand implements Command {
constructor(private editor: TextEditor, private text: string) {}

execute(): void {
this.editor.add(this.text);
}

undo(): void {
this.editor.remove(this.text.length);
}
}

// 利用例
const editor = new TextEditor();
const history: Command[] = [];

const cmd1 = new TypeCommand(editor, "Hello ");
cmd1.execute();
history.push(cmd1);

const cmd2 = new TypeCommand(editor, "World");
cmd2.execute();
history.push(cmd2);

console.log(editor.getContent()); // Hello World

// Undo(巻き戻し)
const last = history.pop();
last?.undo();

console.log(editor.getContent()); // Hello

✅ Explanation

This code uses the Command pattern to encapsulate actions (like typing text) into command objects.
These command objects are stored in a history list and can be undone later using the undo() method.

1. Overview of the Command Pattern

  • Command: Declares the interface for executing and undoing an operation

    • Here: Command
  • ConcreteCommand: Implements the command interface and defines a binding between the action and the receiver

    • Here: TypeCommand
  • Receiver: Knows how to perform the operations associated with a request

    • Here: TextEditor
  • Invoker: Executes the command and stores it for potential undo

    • Here: The history array serves this role

2. Key Classes and Their Roles

  • Command

    • Defines execute() and undo() methods
  • TypeCommand

    • A concrete implementation of Command
    • Adds text to the editor on execute(), and removes it on undo()
  • TextEditor

    • The receiver of the command
    • Manages the text buffer and provides the actual editing operations
  • Client Code

    • Creates TypeCommand objects, executes them, and stores them in a history list
    • Can call undo() on the last command to reverse the operation

3. UML Class Diagram

4. Benefits of the Command Pattern

  • Encapsulation of Operations: Each action is self-contained and easy to store and execute later
  • Undo/Redo Support: Commands can be stored and reversed using the undo() method
  • Flexible History Tracking: Enables logging, replaying, or testing actions independently

This pattern is especially useful when you need to track and manage user actions over time—providing a solid foundation for undo/redo systems and command histories.