The Command Pattern: Turn Actions Into Objects

2026-05-03

Most developers wire user actions directly to the code that performs them — a button click calls deleteRecord(), a menu item calls saveFile(). This works until you need undo/redo, action queuing, macro recording, or audit logging. The Command Pattern solves this by encapsulating a request as an object, letting you parameterize, queue, log, and reverse operations.

A command object has a simple interface: execute() and optionally undo(). Instead of calling business logic directly, you create a command and hand it to an invoker.

Real-world example: a text editor with undo. Without the Command Pattern, your editor has a tangled mess of state-reversal logic scattered everywhere. With it:

The editor maintains a stack of executed commands. Undo pops the top command and calls undo(). Redo pushes it back and calls execute() again. Every new action type you add just needs its own command class — the undo infrastructure never changes.

Where else this shines:

Rule of thumb: if you have more than 3 distinct actions that need to support any combination of undo, queuing, logging, or deferred execution, introduce the Command Pattern. Below that threshold, the indirection costs more than it saves.

Watch out for common mistakes. The biggest one is commands that capture too much state — your command should store only the delta needed to reverse the action, not a snapshot of the entire system. A command that clones the whole document on every keystroke will destroy your memory budget. The second mistake is letting commands hold references to mutable objects that change between execute() and undo(). Commands should capture values, not references, unless you're certain the referenced object won't mutate.

See it in action: Check out Command Actions as Objects by Bug
Coffee to see this theory applied.
Key Takeaway: Wrapping actions as command objects gives you undo, queuing, logging, and replay for free — just make sure each command captures only the minimal state needed to reverse itself.