Перейти к основному содержимому

Паттерн "Команда" в Java — undo в редакторе и очередь действий

Разработчику Архитектору

Обзор — в поведенческих паттернах. Практика на C# (MediatR, ICommand) — в Команда в C#. Здесь — классическая Command на Java с undo/redo.

Загрузка редактора схем…

Задача паттерна

Command превращает запрос в объект с методами execute() и при необходимости undo(). Такой объект можно передать, поставить в очередь, залогировать или отменить.


Пример — текстовый редактор

import java.util.ArrayDeque;
import java.util.Deque;

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

class TextEditor {
private final StringBuilder text = new StringBuilder();

void insert(int pos, String str) {
text.insert(pos, str);
}

void delete(int pos, int length) {
text.delete(pos, pos + length);
}

String getText() {
return text.toString();
}
}

class InsertCommand implements Command {
private final TextEditor editor;
private final int position;
private final String text;

InsertCommand(TextEditor editor, int position, String text) {
this.editor = editor;
this.position = position;
this.text = text;
}

@Override
public void execute() {
editor.insert(position, text);
}

@Override
public void undo() {
editor.delete(position, text.length());
}
}

class CommandHistory {
private final Deque<Command> history = new ArrayDeque<>();

void execute(Command cmd) {
cmd.execute();
history.push(cmd);
}

void undo() {
if (!history.isEmpty()) {
history.pop().undo();
}
}
}
TextEditor editor = new TextEditor();
CommandHistory history = new CommandHistory();

history.execute(new InsertCommand(editor, 0, "Hello"));
history.execute(new InsertCommand(editor, 5, " World"));
System.out.println(editor.getText()); // Hello World

history.undo();
System.out.println(editor.getText()); // Hello

Command в Java-экосистеме

МестоКак проявляется Command
Swing ActionОбъект действия с actionPerformed
JUnit / TestNGИногда оборачивают шаги в команды
CQRSCreateOrderCommand как DTO намерения (см. интеграционные паттерны)

В Spring Boot для HTTP-команд чаще используют сервисные методы или MediatR-подобные библиотеки; учебная схема Command + Handler на C# — в 120.


Когда применять и риски

СитуацияCommand
Undo/redoКаждое действие — класс с обратимой логикой
Очередь, отложенное выполнениеКоманда сериализуется и уходит в worker
МакросыСписок команд выполняется подряд

Минус — много мелких классов. Для одного вызова сервиса достаточно метода без паттерна.

Откат через полный снимок состояния — Memento.


См. также

См. также

Другие статьи этого же раздела в боковом меню (как на странице "О разделе").