Command — это поведенческий паттерн, который превращает запрос в отдельный объект, содержащий всю информацию о запросе.
Простыми словами: вместо прямого вызова метода вы создаёте объект-команду, которую можно передать, поставить в очередь, отменить или повторить.
▪️ Пример:
Текстовый редактор с поддержкой undo/redo: каждое действие — объект, который можно откатить.
// Команда
interface Command {
void execute();
void undo();
}
// Получатель
class TextEditor {
private StringBuilder text = new StringBuilder();
public void insert(int pos, String str) {
text.insert(pos, str);
}
public void delete(int pos, int length) {
text.delete(pos, pos + length);
}
public String getText() { return text.toString(); }
}
// Конкретная команда
class InsertCommand implements Command {
private final TextEditor editor;
private final int position;
private final String text;
public InsertCommand(TextEditor editor, int position, String text) {
this.editor = editor;
this.position = position;
this.text = text;
}
public void execute() {
editor.insert(position, text);
}
public void undo() {
editor.delete(position, text.length());
}
}
// Инвокер с историей
class CommandHistory {
private final Deque<Command> history = new ArrayDeque<>();
public void execute(Command cmd) {
cmd.execute();
history.push(cmd);
}
public 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
▪️ Когда использовать
— Нужен undo/redo
— Команды нужно ставить в очередь, логировать или выполнять отложенно
— Хотите отделить объект, инициирующий операцию, от объекта, выполняющего её
▪️ Минус
Усложняет код: каждая операция — отдельный класс.
🐸 Библиотека собеса по Java
#patterns