Command Palette

Search for a command to run...

PHASE 2Beginner ~7 min· topic 15 of 22Behavioral

Behavioral 3 — Command

In one line

Wrap a request (and its receiver) into an object — enables undo/redo, queuing, logging, and macros.

0/22 · 0%

Key ideas

  1. 01

    Solves: execute later, undo, transactional behavior — GUI actions, job queues, task schedulers.

  2. 02

    Command = execute(); history = stack of commands; undo = reversed execute.

  3. 03

    Many distributed systems (job schedulers, workflow engines) are command patterns at scale.

  4. 04

    Real-life example: a restaurant order slip. The waiter writes your order on paper (the command), the kitchen cooks it later. The slip can be queued, cancelled, or repeated.

  5. 05

    Redo needs a second stack: undo pops from 'history' and pushes onto 'redo'. Any new command clears the redo stack.

Java / Spring map

  • →

    java.lang.Runnable; Spring's TaskExecutor; Quartz jobs.

Code & diagrams

Command.javajava

Undoable text editor operations.

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

public final class TextBuffer {
  private final StringBuilder sb = new StringBuilder();
  public void append(String s) { sb.append(s); }
  public void chop(int n) { sb.setLength(Math.max(0, sb.length() - n)); }
  public String text() { return sb.toString(); }
}

public class AppendCommand implements Command {
  private final TextBuffer buffer; private final String text;
  public AppendCommand(TextBuffer b, String t) { buffer = b; text = t; }
  public void execute() { buffer.append(text); }
  public void undo() { buffer.chop(text.length()); }
}

public class Editor {
  private final Deque<Command> history = new ArrayDeque<>();
  private final Deque<Command> redoStack = new ArrayDeque<>();

  public void run(Command c) { c.execute(); history.push(c); redoStack.clear(); }

  public void undo() {
    if (history.isEmpty()) return;
    Command c = history.pop();
    c.undo();
    redoStack.push(c);
  }

  public void redo() {
    if (redoStack.isEmpty()) return;
    Command c = redoStack.pop();
    c.execute();
    history.push(c);
  }
}

// Demo: e.run(new AppendCommand(buf, "sys")); e.run(new AppendCommand(buf, "-des")); e.undo();

Explain without notes

01

Why does undo/redo need a stack, not a list?

Practice

01

Wrap a MovePiece command for Chess LLD with undo for take-back.

Trade-offs

  • ↔

    Commands multiply per operation type; receivers must expose fine-grained actions.

Completion checklist

  • I can build undo AND redo with two stacks and explain why a new command clears the redo stack.

Back to phase