0Pricing
Java Academy · Урок

Шаблон Command: инкапсуляция действий

Оборачивайте запросы в объекты Command для поддержки отмены, повтора и записи макрокоманд.

«Шаблон Command: инкапсуляция действий» — бесплатный урок Java Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Java Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Java Academy содержит 4 уроков всего.

Назначение Command

Command инкапсулирует запрос как объект, позволяя параметризовать клиентов различными запросами, ставить их в очередь, вести журналирование и выполнять операции с возможностью отмены.

Интерфейс Command

Определите интерфейс с методом execute() и, при необходимости, методом undo(). Каждый объект команды знает, как выполнить и отменить одно действие.

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

Конкретная команда: TextEditor

Каждая конкретная команда инкапсулирует получателя и параметры действия. Выполнение осуществляет действие, а отмена возвращает систему в предыдущее состояние.

public class InsertTextCommand implements Command {
    private final TextEditor editor;
    private final String text;
    private final int position;
    public InsertTextCommand(TextEditor editor, String text, int pos) {
        this.editor = editor; this.text = text; this.position = pos;
    }
    public void execute() { editor.insert(position, text); }
    public void undo()    { editor.delete(position, text.length()); }
}

Вызывающий объект: CommandHistory

Вызывающий объект хранит историю выполненных команд. Он вызывает execute() и помещает команду в стек. Отмена извлекает команду из стека и вызывает undo().

public 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();
    }
}

Стек отмены и повтора

Добавьте стек повтора: при отмене помещайте команду в стек повтора, а при повторе извлекайте её из стека повтора и выполняйте снова.

private final Deque<Command> undoStack = new ArrayDeque<>();
private final Deque<Command> redoStack = new ArrayDeque<>();
public void redo() {
    if (!redoStack.isEmpty()) {
        Command cmd = redoStack.pop();
        cmd.execute();
        undoStack.push(cmd);
    }
}

Макрокоманда

Макрокоманда — это составная команда, содержащая список команд и выполняющая их последовательно. Для отмены выполняются обратные действия в обратном порядке.

public class MacroCommand implements Command {
    private final List<Command> commands;
    public MacroCommand(List<Command> commands) { this.commands = commands; }
    public void execute() { commands.forEach(Command::execute); }
    public void undo()    { for (int i = commands.size()-1; i>=0; i--) commands.get(i).undo(); }
}

Очередь команд для обработки задач

Храните команды в очереди и обрабатывайте их асинхронно. Рабочий поток извлекает команды из очереди и выполняет их, отделяя производителей от потока выполнения.

BlockingQueue<Command> queue = new LinkedBlockingQueue<>();
// Producer:
queue.put(new SendEmailCommand(recipient, subject, body));
// Consumer thread:
Command cmd = queue.take();
cmd.execute();

Команда с исполнителем

Оберните команды в лямбда-выражения Runnable и передайте их в ExecutorService — лямбда-выражение и есть объект команды.

ExecutorService exec = Executors.newFixedThreadPool(4);
exec.submit(() -> sendEmail(recipient, subject));
exec.submit(() -> generateReport(params));

Журналирование команд для аудита

Сериализуемые объекты Command можно сохранять в журнале. При восстановлении воспроизведите их, чтобы воссоздать конечное состояние — это основа источника событий.

void execute(Command cmd) {
    cmd.execute();
    auditLog.append(cmd.toString()); // log every action
    history.push(cmd);
}

Кнопки действий GUI

В средах разработки GUI каждая кнопка или пункт меню содержит объект Command. Нажатие кнопки вызывает command.execute(). Заменяйте команды во время выполнения, чтобы изменять поведение кнопок.

Button saveBtn = new Button("Save");
saveBtn.setOnAction(() -> new SaveDocumentCommand(doc).execute());

Command и стратегия

Оба паттерна инкапсулируют поведение. Стратегия инкапсулирует алгоритм, который можно заменять во время выполнения. Command инкапсулирует полный запрос, включая его параметры и получателя, и поддерживает историю и постановку в очередь.

Command в Spring

Tasklet в Spring Batch и MessageHandler в Spring Integration — это паттерны Command на уровне приложения. Каждый Tasklet инкапсулирует один шаг пакетного задания.

Быстрая проверка

Какой дополнительный метод добавляет Command помимо execute(), чтобы поддержать отмену?

Повторение

Command инкапсулирует действия в виде объектов. Используйте его для стеков отмены и повтора, очередей задач, записи макрокоманд и журналирования аудита. Сочетайте его с вызывающим объектом, который ведёт историю команд.

Часто задаваемые вопросы

Урок «Шаблон Command: инкапсуляция действий» бесплатный?

Да — полный текст урока «Шаблон Command: инкапсуляция действий» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Java Academy, подпишись на CoddyKit PRO. Курс Java Academy содержит 4 уроков всего.

Чему я научусь в уроке «Шаблон Command: инкапсуляция действий»?

Оборачивайте запросы в объекты Command для поддержки отмены, повтора и записи макрокоманд. Ты практикуешь Java Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Java Academy?

Предыдущий опыт не требуется. Java Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Шаблон Command: инкапсуляция действий»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Java Academy?

Да. Каждый урок Java Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Шаблон Observer: уведомление о событиях
  2. Шаблон Strategy: взаимозаменяемые алгоритмы
  3. Шаблон Command: инкапсуляция действий
  4. Шаблон Template Method: каркасы алгоритмов
← Назад к Java Academy