Chaturmind
LearnDSASystem DesignDevOpsEngineering GrowthBlog
Start learning
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML
  • DevOps
  • Engineering Growth

Company

  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Chaturmind. All rights reserved.

Built for engineers who want to go deep.


← Low-Level Design & Design Patterns

OOP Fundamentals & SOLID Principles

  • Object-Oriented Design Refresher
  • Single Responsibility & Open/Closed
  • Liskov Substitution & Interface Segregation
  • Dependency Inversion

Creational Design Patterns

  • Singleton Pattern
  • Factory & Abstract Factory
  • Builder Pattern
  • Prototype Pattern

Structural Design Patterns

  • Adapter & Facade
  • Decorator Pattern
  • Composite & Proxy
  • Bridge & Flyweight

Behavioral Design Patterns

  • Strategy Pattern
  • Observer Pattern
  • Command Pattern
  • Template Method
  • State Pattern
  • Chain of Responsibility
  • Iterator & Mediator
  • Visitor Pattern

Machine Coding Exercises

  • Parking Lot — Requirements & Class Design
  • Parking Lot — Implementation
  • Elevator System — Requirements & Class Design
  • Elevator System — Implementation & Scheduling
  • Library Management System
  • Tic-Tac-Toe / Board Game Design
  • Chess Engine Design
  • Vending Machine Design
  • ATM System Design
  • In-Memory Rate Limiter
  • Thread-Safe LRU Cache
  • Connection Pool Design
  • Producer-Consumer Class Design
  • Movie Ticket Booking System
  • Hotel Reservation System
  • Airline Booking / Seat Selection System
  • Splitwise / Expense Sharing System
  • Design a Logging Framework
  • Design a Notification/Observer-Based Pub-Sub
  • Design a Cache with Pluggable Eviction Policy
  • Design Snake and Ladder
  • Design a Card Game Framework
  • Design an Inventory Management System
  • Restaurant Management System
  • Food Delivery Order Matching
  • Design a Shopping Cart & Checkout Flow
  • Design a Recommendation Engine
  • Design a Job Scheduler
  • Design a Circuit Breaker
  • Design a Distributed ID Generator
  • Design a Pub-Sub Message Broker
  • Design Twitter/X
  • Multi-Pattern Problem: Design a Ride Booking Class Model
  • Multi-Pattern Problem: Design a Food Ordering Class Model
  • Design an Authentication/Authorization Module
  • Design a Form/Survey Builder
  • Design a Meeting Room / Calendar Booking System
  • Design a Search/Filter Engine for an E-Commerce Catalog
  • Design a Voting/Polling System
  • Design a Retry Mechanism with Backoff
  • Design a Health Check Aggregator
  • Design a Feature Flag System
  • Design a Config Management Client
  • Design a Leader Election Algorithm
  • Design a Distributed Counter
  • Design a Bloom Filter
  • Design a Consistent Hashing Ring
  • Design a Distributed Tracing Library
  • Design a Metrics Collection Library
  • Design an Audit Logging Framework
  • Design a Plugin/Extension System
  • Design a Workflow Engine
  • Multi-Pattern Capstone: Design a Food Delivery App
Chaturmind
← Low-Level Design & Design Patterns

OOP Fundamentals & SOLID Principles

  • Object-Oriented Design Refresher
  • Single Responsibility & Open/Closed
  • Liskov Substitution & Interface Segregation
  • Dependency Inversion

Creational Design Patterns

  • Singleton Pattern
  • Factory & Abstract Factory
  • Builder Pattern
  • Prototype Pattern

Structural Design Patterns

  • Adapter & Facade
  • Decorator Pattern
  • Composite & Proxy
  • Bridge & Flyweight

Behavioral Design Patterns

  • Strategy Pattern
  • Observer Pattern
  • Command Pattern
  • Template Method
  • State Pattern
  • Chain of Responsibility
  • Iterator & Mediator
  • Visitor Pattern

Machine Coding Exercises

  • Parking Lot — Requirements & Class Design
  • Parking Lot — Implementation
  • Elevator System — Requirements & Class Design
  • Elevator System — Implementation & Scheduling
  • Library Management System
  • Tic-Tac-Toe / Board Game Design
  • Chess Engine Design
  • Vending Machine Design
  • ATM System Design
  • In-Memory Rate Limiter
  • Thread-Safe LRU Cache
  • Connection Pool Design
  • Producer-Consumer Class Design
  • Movie Ticket Booking System
  • Hotel Reservation System
  • Airline Booking / Seat Selection System
  • Splitwise / Expense Sharing System
  • Design a Logging Framework
  • Design a Notification/Observer-Based Pub-Sub
  • Design a Cache with Pluggable Eviction Policy
  • Design Snake and Ladder
  • Design a Card Game Framework
  • Design an Inventory Management System
  • Restaurant Management System
  • Food Delivery Order Matching
  • Design a Shopping Cart & Checkout Flow
  • Design a Recommendation Engine
  • Design a Job Scheduler
  • Design a Circuit Breaker
  • Design a Distributed ID Generator
  • Design a Pub-Sub Message Broker
  • Design Twitter/X
  • Multi-Pattern Problem: Design a Ride Booking Class Model
  • Multi-Pattern Problem: Design a Food Ordering Class Model
  • Design an Authentication/Authorization Module
  • Design a Form/Survey Builder
  • Design a Meeting Room / Calendar Booking System
  • Design a Search/Filter Engine for an E-Commerce Catalog
  • Design a Voting/Polling System
  • Design a Retry Mechanism with Backoff
  • Design a Health Check Aggregator
  • Design a Feature Flag System
  • Design a Config Management Client
  • Design a Leader Election Algorithm
  • Design a Distributed Counter
  • Design a Bloom Filter
  • Design a Consistent Hashing Ring
  • Design a Distributed Tracing Library
  • Design a Metrics Collection Library
  • Design an Audit Logging Framework
  • Design a Plugin/Extension System
  • Design a Workflow Engine
  • Multi-Pattern Capstone: Design a Food Delivery App
HomeLearnSystem DesignLow-Level Design & Design PatternsBehavioral Design Patterns
✓ FreeIntermediate· 6 min read

Command Pattern

Encapsulating a request as an object to enable undo/redo and queuing — built through a text editor's undo history, and why Command is more than Strategy with a fancier name.

Published September 23, 2026


Command Pattern

The idea: a request as an object, not a method call

A plain method call happens and is gone — there's nothing left to inspect, queue, delay, or undo afterward. Command wraps a request (an action plus the data it needs) into an object, so the request itself becomes a first-class thing you can store, pass around, and reverse.

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

class TextDocument {
    private final StringBuilder content = new StringBuilder();
    void insert(int pos, String text) { content.insert(pos, text); }
    void delete(int pos, int length) { content.delete(pos, pos + length); }
    String getText() { return content.toString(); }
}

class InsertCommand implements Command {
    private final TextDocument doc;
    private final int position;
    private final String text;

    InsertCommand(TextDocument doc, int position, String text) {
        this.doc = doc; this.position = position; this.text = text;
    }
    public void execute() { doc.insert(position, text); }
    public void undo() { doc.delete(position, text.length()); } // the exact inverse of execute()
}

Undo/redo via a command history stack

class EditorHistory {
    private final Deque<Command> undoStack = new ArrayDeque<>();
    private final Deque<Command> redoStack = new ArrayDeque<>();

    void executeCommand(Command cmd) {
        cmd.execute();
        undoStack.push(cmd);
        redoStack.clear(); // a fresh action invalidates any previously-undone redo history
    }

    void undo() {
        if (undoStack.isEmpty()) return;
        Command cmd = undoStack.pop();
        cmd.undo();
        redoStack.push(cmd);
    }

    void redo() {
        if (redoStack.isEmpty()) return;
        Command cmd = redoStack.pop();
        cmd.execute();
        undoStack.push(cmd);
    }
}

Every executed command is pushed onto undoStack after running. Undo pops the most recent one and calls its undo() — moving it to redoStack so redo can re-execute it later. The redoStack.clear() on a fresh action is the detail easy to miss: once you undo twice and then type something new, the two undone actions are no longer a valid "redo" path — they'd redo into a document state that no longer makes sense given the new edit.

Command vs Strategy — both wrap behavior, different purpose

Strategy (see Strategy Pattern) wraps an interchangeable algorithm — the point is picking which implementation runs, with no concept of "undo" or "when." Command wraps a request, specifically so it can be queued, delayed, logged, or reversed — the "when" (execute now? later? as part of a batch?) and the "undo" are exactly what Command adds that Strategy doesn't model at all. A PricingStrategy has no meaningful "undo"; an InsertCommand does, by design.

Follow-up questions this topic invites — and their answers

Q: How would you implement a 'macro' — a single command that bundles several commands together? A: A CompositeCommand implementing the same Command interface, holding a List<Command>, whose execute() runs each child in order and whose undo() undoes them in reverse order — this is Command combined with Composite (see Composite & Proxy), and the reverse-order undo is the detail that makes it correct: undoing must unwind history in the opposite order it was built.

Q: Why does InsertCommand.undo() call doc.delete() instead of storing a full document snapshot? A: Storing the minimal inverse operation (delete the exact range that was inserted) is far cheaper than snapshotting the whole document before every command — this matters a lot for a text editor where documents can be large and edits are frequent; snapshot-based undo only makes sense when computing a precise inverse operation is itself impractical.

Q: Can Command be used for something other than undo/redo? A: Yes — queuing (store commands in a queue and execute them later, e.g. a job queue), logging/auditing (every command object is a natural audit-log entry of what happened and when), and remote execution (serialize a command object and execute it on a different machine) are all common Command applications that have nothing to do with undo.

Q: What happens to undo() correctness if InsertCommand's undo() assumes nothing else modified the document between execute() and undo()? A: It breaks — if another command inserted or deleted text at an overlapping position in between, the stored position/length in InsertCommand.undo() would delete the wrong range. This is why undo/redo systems generally require commands to be undone in strict LIFO order relative to how they were executed (which the stack-based EditorHistory above enforces by construction) rather than allowing arbitrary out-of-order undo.

Previous

Observer Pattern

Next

Template Method

AI Tutor

Lesson: Command Pattern

Quick actions

AI responses can be inaccurate. Verify critical information.