Low-Level Design (LLD)
PatternsBehavioral Patterns·5 min revision·Updated 2026-10-29

Command Pattern

Command Pattern → encapsulate request as object → caller can execute, queue, retry, log, or undo request without knowing implementation details.

#LLD#Patterns#Java#Command Pattern
1-Minute Revision Card
Command Pattern
Core Entities & Components
CommandFactoryCommandInterfaceConcreteProduct
Architecture & Patterns
Command Pattern
Key Methods, APIs & Formulas
create()getInstance()process()
Exact Phrases to Say in the Interview
  • “I will apply Command Pattern here to encapsulate changes and satisfy Open/Closed principle.”
  • “De-couples core execution from specific implementations.”

Command Pattern

Command Pattern

1. ONE-LINE IDEA

Command Pattern → encapsulate request as object → caller can execute, queue, retry, log, or undo request without knowing implementation details.

Example: Remote control sends commands to TV.

2. PROBLEM

Java

java
if (action.equals("ON")) {
    tv.turnOn();
} else if (action.equals("OFF")) {
    tv.turnOff();
} else if (action.equals("VOLUME_UP")) {
    tv.increaseVolume();
}

Problems:

  • Remote tightly coupled to TV.
  • New action → modify remote logic.
  • Hard to queue, log, or undo actions.
  • Different devices require different conditionals.

Solution: Each request becomes its own command object.

3. REQUIREMENTS

Functional:

  • Execute different device operations through common interface.
  • Support multiple devices.
  • Allow caller to invoke commands without knowing receiver.
  • Support undo for reversible operations.
  • Allow commands to be swapped dynamically.

Out of scope: Persistent command queue, distributed execution, crash recovery.

4. CORE ENTITIES

  • Command → common execute() contract.
  • LightOnCommand / LightOffCommand → concrete commands.
  • Light → receiver; performs actual work.
  • RemoteControl → invoker; triggers command.
  • Main → client; wires objects together.

5. UML CLASS DIAGRAM

plain
Client
  |
  | configures
  v
RemoteControl (Invoker)
  |
  | has
  v
Command (Interface)
  ^
  |
  +-------------------+
  |                   |
LightOnCommand    LightOffCommand
  |                   |
  +---------+---------+
            |
            v
         Light
       (Receiver)

Relationships:

  • RemoteControl → association with Command.
  • Concrete commands → realize Command.
  • Concrete commands → hold reference to receiver Light.
  • Client wires invoker + command + receiver.

6. FULL JAVA 17 IMPLEMENTATION

Java

java
interface Command {
    void execute();
    void undo();
}

final class Light {
    private boolean on;

    public void turnOn() {
        on = true;
        System.out.println("Light ON");
    }

    public void turnOff() {
        on = false;
        System.out.println("Light OFF");
    }

    public boolean isOn() {
        return on;
    }
}

final class LightOnCommand implements Command {
    private final Light light;

    public LightOnCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
        light.turnOn();
    }

    @Override
    public void undo() {
        light.turnOff();
    }
}

final class LightOffCommand implements Command {
    private final Light light;

    public LightOffCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
        light.turnOff();
    }

    @Override
    public void undo() {
        light.turnOn();
    }
}

final class RemoteControl {
    private Command command;
    private Command lastExecuted;

    public void setCommand(Command command) {
        this.command = command;
    }

    public void pressButton() {
        if (command == null) {
            throw new IllegalStateException(
                "No command configured"
            );
        }

        command.execute();
        lastExecuted = command;
    }

    public void undoLastCommand() {
        if (lastExecuted == null) {
            System.out.println("Nothing to undo");
            return;
        }

        lastExecuted.undo();
        lastExecuted = null;
    }
}

public class Main {
    public static void main(String[] args) {
        Light light = new Light();

        Command on = new LightOnCommand(light);
        Command off = new LightOffCommand(light);

        RemoteControl remote = new RemoteControl();

        remote.setCommand(on);
        remote.pressButton();

        remote.undoLastCommand();

        remote.setCommand(off);
        remote.pressButton();
    }
}

Output:

plain
Light ON
Light OFF
Light OFF

7. EXECUTION FLOW

plain
Client configures command
          |
          v
RemoteControl.setCommand(command)
          |
          v
RemoteControl.pressButton()
          |
          v
Command.execute()
          |
          v
Light.turnOn()

Invoker doesn't know how light turns on. It only knows Command.

8. UNDO — IMPORTANT DETAIL

Simple undo() works here because operations are reversible and inverse is obvious.

For general commands, store previous state:

Java

java
final class SetVolumeCommand implements Command {
    private final Stereo stereo;
    private final int newVolume;
    private int previousVolume;

    public SetVolumeCommand(Stereo stereo, int newVolume) {
        this.stereo = stereo;
        this.newVolume = newVolume;
    }

    @Override
    public void execute() {
        previousVolume = stereo.getVolume();
        stereo.setVolume(newVolume);
    }

    @Override
    public void undo() {
        stereo.setVolume(previousVolume);
    }
}

Assumes Stereo provides getVolume() and setVolume(int).

Caveat: Current remote remembers only last command. Real undo/redo needs command history stack; repeated execution may require separate history entries.

9. DESIGN PATTERNS USED TOGETHER

  • Command + Composite: macro command executes multiple commands.
  • Command + Memento: save previous state for undo.
  • Command + Queue: enqueue requests for async execution.
  • Command + Strategy: both encapsulate behavior, but intent differs.

Command vs Strategy

CommandStrategy
Represents request/actionRepresents algorithm
Often has execute() / undo()Usually has operation-specific method
Supports queue, history, loggingSwaps behavior/algorithm
Example: TurnOnCommandExample: PaymentStrategy

10. INTERVIEW QUESTIONS

Q: Why not call receiver directly?

Invoker becomes coupled to receiver. Command isolates request from execution.

Q: Who creates commands?

Usually client or DI/configuration layer.

Q: Can commands be queued?

Yes. Store Command objects in queue and execute them via worker.

Q: Can commands be retried safely?

Only if retry semantics are safe. For payments or external APIs, use idempotency keys and durable execution state.

Q: Is Command Pattern thread-safe?

Not automatically. Shared receiver state, mutable commands, and command history need synchronization where concurrent access exists.

Q: Real-world uses?

  • GUI button actions
  • Undo/redo editors
  • Job queues
  • Transaction workflows
  • Smart-home controls
  • Task scheduling

11. COMPLEXITY

For this implementation:

  • setCommand() → O(1)O(1)O(1)
  • pressButton() → O(1)O(1)O(1), excluding receiver work
  • undoLastCommand() → O(1)O(1)O(1), excluding undo work
  • Space → O(1)O(1)O(1) for current/last command refs

Command history stack would use O(H)O(H)O(H) space for HHH recorded commands.

12. QUICK REVISION

  • Command → request object.
  • Receiver → performs work.
  • Invoker → triggers command.
  • Client → wires objects.
  • execute() → perform action.
  • undo() → reverse action where possible.
  • Queue/history → major benefit.

13. MEMORY TRICK

Client creates → Invoker triggers → Command delegates → Receiver acts.

Abhinandan Mishra

SDE-II · Distributed Systems · Developer Tools

© 2026 Abhinandan Mishra

Built with Next.js & Tailwind CSS

abhinandanmishra360@gmail.com