7. Command, Memento Pattern

Command, Memento, and Mediator Design Patterns

Command Pattern

Definition

The Command Pattern is a behavioral design pattern that encapsulates a request as an object, thereby enabling developers to parameterize clients with queues, requests, and operations. It also allows for the support of undoable operations.

Key Points

Example

A typical example of the Command Pattern can be demonstrated in a simple calculator implementation.

// Command
public interface Command {
    void execute();
    void unexecute();
}

// ConcreteCommand
public class CalculatorCommand implements Command {
    private Calculator calculator;
    private char operator;
    private int operand;

    public CalculatorCommand(Calculator calculator, char operator, int operand) {
        this.calculator = calculator;
        this.operator = operator;
        this.operand = operand;
    }

    public void execute() {
        calculator.operation(operator, operand);
    }

    public void unexecute() {
        calculator.operation(undo(operator), operand);
    }

    private char undo(char operator) {
        switch (operator) {
            case '+': return '-';
            case '-': return '+';
            case '*': return '/';
            case '/': return '*';
            default: throw new IllegalArgumentException("Invalid operator");
        }
    }
}

Memento Pattern

Definition

The Memento Pattern is a behavioral design pattern that allows you to save and restore the previous state of an object without exposing the details of its implementation. This pattern is commonly used for implementing undo mechanisms.

Key Points

Example

An example of the Memento Pattern can be seen in a text editor's undo operation.

// Memento
public class EditorState {
    private final String content;

    public EditorState(String content) {
        this.content = content;
    }

    public String getContent() {
        return content;
    }
}

// Originator
public class Editor {
    private String content;

    public EditorState createState() {
        return new EditorState(content);
    }

    public void restore(EditorState state) {
        content = state.getContent();
    }
}

// Caretaker
public class History {
    private Stack<EditorState> states = new Stack<>();

    public void push(EditorState state) {
        states.push(state);
    }

    public EditorState pop() {
        return states.pop();
    }
}

Mediator Pattern

Definition

The Mediator Pattern is a behavioral design pattern that reduces chaotic dependencies among objects. The pattern restricts direct communications between the objects and forces them to collaborate only via a mediator object.

Key Points

Example

An example of the Mediator Pattern can be seen in a chat room implementation.

// Mediator
public interface ChatMediator {
    void sendMessage(String msg, User user);
    void addUser(User user);
}

// ConcreteMediator
public class ChatRoom implements ChatMediator {
    private List<User> users;

    public ChatRoom() {
        this.users = new ArrayList<>();
    }

    public void addUser(User user) {
        this.users.add(user);
    }

    public void sendMessage(String msg, User user) {
        for (User u : this.users) {
            // message should not be received by the user sending it
            if (u != user) {
                u.receive(msg);
            }
        }
    }
}

The Command, Memento, and Mediator patterns are essential parts of software engineering and can help solve complex problems in an organized and efficient manner.

Reference

The content in this document is based on the original notes provided in Azerbaijani. For further details, you can refer to the original document using the following link:

Original Note - Azerbaijani Version