Command is strongest when you need to represent an action as an object with its own execution lifecycle.
Encapsulate a request as an object so you can parameterize clients with operations, queue them, log them, or support undo-like workflows.
What the pattern is trying to do
Encapsulate a request as an object so you can parameterize clients with operations, queue them, log them, or support undo-like workflows.
What force creates the need
Actions need to be scheduled, stored, retried, audited, or executed later, but raw method calls are too tightly bound to the caller.
How the pattern responds
Model each action as a command object that carries the logic and context needed to execute the request.
How the moving parts fit together
An invoker triggers commands through a common interface, while each command delegates actual work to domain services or receivers.
Java example in the Order Management domain
package org.javaomnibus.ecommerce.gof.behavioral;
public interface OrderCommand {
void execute();
}
public final class CapturePaymentCommand implements OrderCommand {
private final PaymentService paymentService;
private final Order order;
public CapturePaymentCommand(PaymentService paymentService, Order order) {
this.paymentService = paymentService;
this.order = order;
}
@Override
public void execute() {
paymentService.capture(order);
}
}
Step by step
- The command packages one executable action plus its context.
- An invoker can execute commands immediately or later.
- This makes queueing, auditing, and retry-oriented workflows more explicit.
- Command is about actions as objects, not just policy variation.
Where this pattern helps
- When operations need queueing, retries, scheduling, or audit trails
- When UI, workflow, or batch systems trigger actions indirectly
When a simpler design is better
- When a direct method call is simpler and no action lifecycle exists
- When the real need is algorithm variation rather than action representation
What this pattern costs
- Adds object overhead and more types
- Command-heavy systems can become noisy if every trivial call becomes a command
How this fits today
Command still matters in Java where workflows, messaging, background jobs, and audit-sensitive actions need a first-class representation.
Where teams get it wrong
Creating command objects for tiny synchronous operations with no scheduling or lifecycle value often adds ceremony without benefit.