Search Knowledge

© 2026 LIBREUNI PROJECT

Software Engineering & OOAD / Design Patterns

Command & State Patterns

Command & State Patterns

Behavioral patterns allow us to manage the “how” of object interaction. The Command pattern focuses on encapsulating requests for later execution or undoing, while the State pattern focuses on how object behavior changes as its internal state evolves.


1. The Command Pattern

The Problem

If you’re building a GUI with buttons, you might have a “Save” button and a “Copy” button. You don’t want the Button class to know exactly what logic to execute (e.g., saveDatabase() or copyToClipboard()). If you hardcode this logic into the Button class, you can’t reuse it for other purposes (like a keyboard shortcut or a menu item).

The Solution

The Command pattern turns a request into a stand-alone object that contains all information about the request. This transformation lets you pass requests as method arguments, delay or queue a request’s execution, and support undoable operations.

The setup usually involves:

  • Command: Declares the interface.
  • ConcreteCommand: Implements the call to the Receiver.
  • Receiver: Knows how to perform the actual work (the “Logic”).
  • Invoker: Triggers the command (e.g., the Button).

Java Implementation (with Undo)

// 1. Command Interface
interface Command {
    void execute();
    void undo();
}

// 2. Receiver
class Light {
    public void on() { System.out.println("Light is ON"); }
    public void off() { System.out.println("Light is OFF"); }
}

// 3. Concrete Command
class LightOnCommand implements Command {
    private Light light;
    public LightOnCommand(Light light) { this.light = light; }

    public void execute() { light.on(); }
    public void undo() { light.off(); }
}

// 4. Invoker
class RemoteControl {
    private Command command;
    public void setCommand(Command command) { this.command = command; }
    public void pressButton() { command.execute(); }
    public void pressUndo() { command.undo(); }
}

Pros and Cons

  • Pros: Decouples the object that triggers the operation from the one that knows how to perform it. Supports Undo/Redo.
  • Cons: The code can become quite complicated since you’re introducing a whole new layer between senders and receivers.

2. The State Pattern

The Problem

Consider a Document class in an editor. It can be in one of three states: Draft, Moderation, or Published. In each state, the publish() method behaves differently:

  • In Draft, it moves the doc to Moderation.
  • In Moderation, it makes the doc Published if the user is an admin.
  • In Published, it does nothing. Using many if-else or switch statements for every method of the Document class leads to messy code that is hard to maintain.

The Solution

The State pattern lets an object alter its behavior when its internal state changes. The object will appear to change its class.

The key is to extract state-specific behaviors into separate “State” classes and delegate the work to the current state object.

Python Example

from abc import ABC, abstractmethod

# 1. State Interface
class State(ABC):
    @abstractmethod
    def publish(self, document):
        pass

# 2. Concrete States
class DraftState(State):
    def publish(self, document):
        print("Moving document from Draft to Moderation.")
        document.set_state(ModerationState())

class ModerationState(State):
    def publish(self, document):
        print("Reviewing document... Approved! Moving to Published.")
        document.set_state(PublishedState())

class PublishedState(State):
    def publish(self, document):
        print("Document is already published. Doing nothing.")

# 3. Context (Document)
class Document:
    def __init__(self):
        self._state = DraftState()

    def set_state(self, state: State):
        self._state = state

    def publish(self):
        self._state.publish(self)

# Usage
doc = Document()
doc.publish() # Moves to Moderation
doc.publish() # Moves to Published
doc.publish() # Already published

Strategy vs. State

While the class diagrams look identical (a Context class holding a reference to an Interface), the intent is different:

  • State: Objects know about each other and transition from one state to another.
  • Strategy: Strategies are usually independent and unaware of each other; the client chooses which one to use.

Pros and Cons

  • Pros: Adheres to the Single Responsibility Principle. Eliminates massive conditional state machines.
  • Cons: Can be overkill if a state machine has only a few states or rarely changes.