Behavioral PatternsCommand PatternHard⏱️ ~3 min

Command Pattern: Trade-offs & When to Use

When to Use Command Pattern

Use Command Pattern when you need undo/redo functionality with reversible operations. The pattern naturally supports this because commands store state. Use it when you need to queue operations for deferred execution, such as background task processors or transaction systems. Use it when you have multiple triggers for the same operation (button, menu, keyboard shortcut) and want to avoid code duplication. Use it when building macro systems where users record and replay sequences of actions. Finally, use it when you need audit logging of all operations performed on a system.

When Command is Overkill

Do not use Command Pattern for simple CRUD operations where undo is not needed and operations are never queued. Direct method calls are simpler and appropriate instead. Avoid it for stateless operations that have no parameters or side effects, as creating command objects adds unnecessary complexity. Skip it when you have operations that cannot be undone, such as sending emails or making external API calls, unless you need queuing or logging. For one-off actions triggered from a single place with no reuse, the abstraction overhead is not justified.

Without Command (Problem)
BoldButton directly calls editor.applyBold(). No way to undo. Menu and keyboard shortcut duplicate logic. Cannot queue or log operations.
With Command (Solution)
BoldButton creates BoldCommand and passes to CommandHistory. All triggers reuse same command. Full undo/redo. Queueable and loggable.

Alternative Patterns

Strategy Pattern: Use Strategy instead of Command when you need to swap algorithms at runtime but do not need undo or queuing. Strategy encapsulates algorithms, Command encapsulates requests. If you are selecting different sorting methods, use Strategy. If you are making operations reversible, use Command.

Memento Pattern: Use Memento when undo requires capturing entire object state, not just command parameters. Memento saves snapshots of the Receiver. Command stores undo information in the command itself. For a text editor, Command is lighter (store deleted text). For a complex game state, Memento might be simpler (snapshot entire game state). However, Memento and Command often work together: Command for granular undo, Memento for checkpoints.

Observer Pattern: Use Observer when multiple objects need to react to state changes. Command is about encapsulating actions, Observer is about notification. They solve different problems, but Command can trigger Observers. For example, SaveCommand executes and notifies UI observers to update save status.

Key Trade-offs

Flexibility vs Complexity: Command Pattern adds classes for every operation. A simple app with 20 actions now has 20 command classes plus invokers and history managers. This is justified when you need undo/queuing, but overkill for simple apps. If you only have 2-3 operations and no undo, direct calls are appropriate instead.

Memory vs Functionality: Storing commands for undo consumes memory, especially for fine-grained operations. Typing individual characters each becomes a command. Solution: batch commands (group characters into words) or limit undo history depth. For resource-constrained environments, consider if full undo is worth the memory cost.

Coupling: Command reduces coupling between invoker and receiver but introduces coupling between command and receiver. BoldCommand must know TextEditor interface. This is acceptable because commands are specific to their domain. However, if commands become too aware of receiver internals, you lose encapsulation benefits.

Interview Tip: Mention that modern frameworks (React, Angular) often handle undo through state management (Redux time travel) rather than Command Pattern. Command is essential for desktop apps and embedded systems but might be replaced by state snapshots in web apps. However, for machine coding rounds, Command Pattern with explicit classes is expected.
💡 Key Takeaways
Use Command for undo/redo, queuing, macros, and audit logging
Overkill for simple CRUD, stateless operations, or non-reversible actions
Alternative: Strategy for algorithm selection, Memento for state snapshots
Trade-off: Increased classes and memory vs flexibility and features
Modern state management can replace Command in some web applications
📌 Examples
1Use: Photoshop with hundreds of undoable operations
2Use: Task scheduler queuing background jobs
3Avoid: Simple form submit with no undo or queuing needs
← Back to Command Pattern Overview