# How to Implement the Command Pattern with Undo/Redo Functionality in Java

> Learn to implement the Command pattern with undo/redo in Java using Deque stacks. Discover how toggle commands reverse effects with this practical example from java-design-patterns.

- Repository: [Ilkka Seppälä/java-design-patterns](https://github.com/iluwatar/java-design-patterns)
- Tags: how-to-guide
- Published: 2026-02-27

---

**Implement the Command pattern with undo/redo by using two `Deque` stacks to store `Runnable` commands, where re-executing toggle commands reverses their effect, as demonstrated in the `iluwatar/java-design-patterns` repository.**

The Command pattern decouples the object that invokes an operation from the object that performs it, enabling powerful features like undo and redo history. In the `iluwatar/java-design-patterns` repository, this pattern is implemented through a wizard casting spells on a goblin, demonstrating how to implement the Command pattern with undo/redo functionality in Java using method references and stack-based history management.

## Understanding the Command Pattern Architecture

The Command pattern involves four key roles that work together to encapsulate requests as objects. The **Client** creates commands and configures the receiver, the **Command** encapsulates the request as an object, the **Invoker** triggers execution, and the **Receiver** performs the actual business logic. In the Java Design Patterns implementation, these roles map to specific classes that demonstrate clean separation of concerns while supporting undo and redo operations through toggle semantics.

## Core Components in the Java Design Patterns Implementation

### The Receiver (Target and Goblin)

The receiver maintains the application state that commands manipulate. In [`Target.java`](https://github.com/iluwatar/java-design-patterns/blob/main/Target.java), abstract methods define the interface for state changes, while [`Goblin.java`](https://github.com/iluwatar/java-design-patterns/blob/main/Goblin.java) provides concrete implementations for `changeSize()` and `changeVisibility()`. These methods use toggle semantics, switching between enum values like `Size.SMALL` and `Size.NORMAL`, which enables undo functionality through simple re-execution rather than complex state restoration logic.

### The Command (Runnable Method References)

Rather than creating dedicated command classes, the implementation leverages Java's functional interfaces to minimize boilerplate. Commands are represented as `Runnable` method references such as `goblin::changeSize` or `goblin::changeVisibility`. This approach reduces code complexity while maintaining the pattern's intent, as each `Runnable` encapsulates the invocation of a specific receiver method without requiring additional class definitions.

### The Invoker (Wizard with Undo/Redo Stacks)

The `Wizard` class in [`Wizard.java`](https://github.com/iluwatar/java-design-patterns/blob/main/Wizard.java) serves as the invoker, managing command execution and history through two `Deque<Runnable>` instances. The `undoStack` stores executed commands, while the `redoStack` maintains commands that have been undone. The `castSpell(Runnable)` method executes commands and pushes them onto the undo stack, while `undoLastSpell()` and `redoLastSpell()` manage history navigation by transferring commands between stacks and re-executing them to toggle state.

## Implementing Undo and Redo Functionality

The undo mechanism relies on the toggle semantics of receiver methods rather than separate undo logic. When `undoLastSpell()` is called in [`Wizard.java`](https://github.com/iluwatar/java-design-patterns/blob/main/Wizard.java), the command is popped from `undoStack`, pushed onto `redoStack`, and executed again. Because methods like `changeSize()` toggle between states, re-executing the same command reverses the previous effect, effectively undoing the operation without requiring additional state storage.

Redo functionality mirrors this process exactly. The `redoLastSpell()` method transfers commands from `redoStack` back to `undoStack` and executes them, restoring the state to what it was before the undo. This stack-based approach provides O(1) time complexity for all operations, making it efficient for interactive applications requiring rapid history navigation.

## Practical Code Examples

The following example from [`App.java`](https://github.com/iluwatar/java-design-patterns/blob/main/App.java) demonstrates the complete workflow:

```java
public static void main(String[] args) {
    var wizard = new Wizard();          // invoker
    var goblin = new Goblin();          // receiver

    // initial state
    goblin.printStatus();

    // cast two spells (commands are method references)
    wizard.castSpell(goblin::changeSize);
    goblin.printStatus();

    wizard.castSpell(goblin::changeVisibility);
    goblin.printStatus();

    // undo the last two spells
    wizard.undoLastSpell();
    goblin.printStatus();

    wizard.undoLastSpell();
    goblin.printStatus();

    // redo them
    wizard.redoLastSpell();
    goblin.printStatus();

    wizard.redoLastSpell();
    goblin.printStatus();
}

```

For a custom implementation, consider this light switch example using the same pattern:

```java
public class Light {
    private boolean on = false;
    
    public void toggle() { 
        on = !on; 
        System.out.println("Light is " + (on ? "ON" : "OFF")); 
    }
}

// Usage
Wizard wizard = new Wizard();
Light lamp = new Light();

wizard.castSpell(lamp::toggle);   // Light turns ON
wizard.undoLastSpell();           // Light turns OFF (undo)
wizard.redoLastSpell();           // Light turns ON again (redo)

```

## Key Files and Source Locations

The implementation is organized in the `command` module of the repository:

- [`App.java`](https://github.com/iluwatar/java-design-patterns/blob/main/App.java) – Entry point demonstrating the wizard and goblin interaction: [`command/src/main/java/com/iluwatar/command/App.java`](https://github.com/iluwatar/java-design-patterns/blob/main/command/src/main/java/com/iluwatar/command/App.java)
- [`Wizard.java`](https://github.com/iluwatar/java-design-patterns/blob/main/Wizard.java) – Invoker class managing undo/redo stacks: [`command/src/main/java/com/iluwatar/command/Wizard.java`](https://github.com/iluwatar/java-design-patterns/blob/main/command/src/main/java/com/iluwatar/command/Wizard.java)
- [`Target.java`](https://github.com/iluwatar/java-design-patterns/blob/main/Target.java) – Abstract receiver defining the interface: [`command/src/main/java/com/iluwatar/command/Target.java`](https://github.com/iluwatar/java-design-patterns/blob/main/command/src/main/java/com/iluwatar/command/Target.java)
- [`Goblin.java`](https://github.com/iluwatar/java-design-patterns/blob/main/Goblin.java) – Concrete receiver implementing toggle methods: [`command/src/main/java/com/iluwatar/command/Goblin.java`](https://github.com/iluwatar/java-design-patterns/blob/main/command/src/main/java/com/iluwatar/command/Goblin.java)
- [`Size.java`](https://github.com/iluwatar/java-design-patterns/blob/main/Size.java) & [`Visibility.java`](https://github.com/iluwatar/java-design-patterns/blob/main/Visibility.java) – Enum definitions for receiver state: [`command/src/main/java/com/iluwatar/command/Size.java`](https://github.com/iluwatar/java-design-patterns/blob/main/command/src/main/java/com/iluwatar/command/Size.java), [`command/src/main/java/com/iluwatar/command/Visibility.java`](https://github.com/iluwatar/java-design-patterns/blob/main/command/src/main/java/com/iluwatar/command/Visibility.java)
- [`CommandTest.java`](https://github.com/iluwatar/java-design-patterns/blob/main/CommandTest.java) – Unit tests verifying undo/redo behavior: [`command/src/test/java/com/iluwatar/command/CommandTest.java`](https://github.com/iluwatar/java-design-patterns/blob/main/command/src/test/java/com/iluwatar/command/CommandTest.java)

## Summary

- The Command pattern decouples invokers from receivers by encapsulating requests as objects, enabling undo/redo functionality through history management.
- The `iluwatar/java-design-patterns` implementation uses `Runnable` method references as lightweight commands, eliminating boilerplate while maintaining pattern semantics.
- Undo and redo rely on two `Deque<Runnable>` stacks (`undoStack` and `redoStack`) in the `Wizard` class, providing O(1) operation complexity.
- Toggle semantics in receiver methods (`changeSize`, `changeVisibility`) allow the same command to serve as both action and undo operation through re-execution.
- For complex scenarios requiring parameter storage or non-toggle logic, extend the pattern by implementing a dedicated `Command` interface with explicit `execute()` and `undo()` methods while retaining the stack-based history approach.

## Frequently Asked Questions

### How does the Command pattern enable undo functionality without separate undo methods?

The implementation leverages **toggle semantics** in the receiver methods. When a command like `changeSize()` is executed, it switches the goblin between `SMALL` and `NORMAL` states. The `Wizard` stores these commands in an `undoStack`, and when undo is requested, it re-executes the same command, which toggles the state back to its previous value. This eliminates the need for separate "unexecute" methods while maintaining clean separation between invoker and receiver.

### Why does the implementation use `Runnable` instead of a custom Command interface?

The repository uses `Runnable` as the command interface to **minimize boilerplate code** while preserving the pattern's intent. Java 8+ method references (such as `goblin::changeSize`) automatically satisfy the `Runnable` interface, allowing commands to be created without dedicated classes. This approach is sufficient for simple toggle operations, though complex scenarios requiring parameter storage or multi-step undo logic would benefit from a custom interface with explicit `execute()` and `undo()` methods.

### What is the time complexity of undo and redo operations in this implementation?

Both **undo and redo operations execute in O(1) time complexity**. The `Wizard` class uses `Deque<Runnable>` instances (specifically `LinkedList` implementations) for the `undoStack` and `redoStack`. Popping from and pushing to either end of a `Deque` is a constant-time operation. This efficiency makes the pattern suitable for interactive applications requiring rapid history navigation, such as text editors or drawing programs.

### How would you extend this pattern to support commands with parameters or non-toggle semantics?

For commands requiring **parameters or complex state restoration**, replace the `Runnable` interface with a custom `Command` interface containing `execute()` and `undo()` methods. The concrete command objects would store the receiver reference, parameter values, and the previous state before execution. The `undo()` method would restore the saved state rather than re-executing the command. The `Wizard` class would remain unchanged, simply storing `Command` objects instead of `Runnable` instances in its history stacks, preserving the O(1) undo/redo performance.