Conceptly
← All Concepts
πŸ“‹

Command

BehavioralA behavioral pattern that encapsulates requests as objects for execution, undo, and queuing

Command is a pattern that turns a request -- 'do this' -- into a standalone object. The side sending the request (Invoker) does not know what the request specifically does or how, and the side performing the work (Receiver) does not know who requested it. Once a request becomes an object, it can be stored, transmitted, undone, and replayed.

β–ΆArchitecture Diagram

πŸ”„ Process

Dashed line animations indicate the flow direction of data or requests

Why do you need it?

Consider building a GUI where pressing a button triggers an action. If the action is coded directly inside the button, duplicating the same action for a menu, keyboard shortcut, or context menu means duplicating the code. When an 'undo' feature is needed, the problem grows: you must remember what action ran when, and also hold a way to reverse it. If actions are scattered as function calls, there is no object to serve as a history record.

Why did this approach emerge?

Command's roots trace back to 1970s operating-system job scheduling. Representing tasks as data structures made it possible to enqueue them, assign priorities, and log them. When the GUI era arrived, the idea moved to the application level. Implementing undo/redo in a text editor required recording each user action in a reversible form, and that recording unit became the Command object. Since GoF formalized it, the structure has been used as a core building block in architectural patterns like message queues, CQRS (Command Query Responsibility Segregation), and event sourcing.

How does it work inside?

Command has four roles. The Command interface defines execute(). A Concrete Command implements that interface, holding a Receiver reference and the parameters needed for execution. The Invoker receives and stores a Command object, calling execute() at the appropriate moment. The Receiver performs the actual business logic. The flow works like this: the Client creates a Receiver, creates a Command containing that Receiver, and registers it with the Invoker. The Invoker fires execute() on a trigger (button click, schedule, event), and the Command delegates the real work to its internal Receiver. To support undo, an undo() method is added to the Command, and the Invoker pushes executed Commands onto a stack. On an undo request, the top Command is popped and undo() is called. This structure makes extensions like execution-history management, macros (bundling multiple Commands into one), and transactions (execute all or undo all) straightforward.

What is it often confused with?

Command and Strategy both wrap behavior in objects, but the intent differs. Strategy is about 'performing the same task in a different way' by swapping algorithms; Command is about 'recording what was done and controlling it' by objectifying requests. Strategy cares about algorithm replacement; Command cares about execution timing, history, and undo. Confusion with Observer is also possible. Observer propagates a state change to multiple recipients, while Command turns a single request into an object and manages its lifecycle (creation, delivery, execution, undo). They are often used together in event systems: Observer propagates the event, and inside a handler a Command object is executed.

When should you use it?

Command's most compelling use case is undo/redo. In text editors, graphic editors, and spreadsheets, recording every user operation as a Command means undo is implemented simply by rewinding the stack. It is also valuable for job queues. Serializing requests into Command objects lets them be sent across the network to another server or queued for a worker to process later. When transaction boundaries are needed, multiple Commands are bundled: all execute() or, if any fails, all undo(). The signals for adoption are 'this action must be reversible,' 'this request must be executed later,' or 'action history must be recorded.' If a simple method call suffices and neither history nor undo is needed, there is no reason to introduce Command.

Undo/Redo -- managing action history in text editors and graphic toolsTransactions -- grouping multiple operations into one unit for execution or rollbackMacros -- recording a sequence of commands and replaying them as a batchJob queue -- enqueuing requests for workers to process sequentially