Назад к вопросам
Middle
73
questionbank

Зачем используется паттерн Command?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Паттерн Command используется для инкапсуляции запроса в виде объекта, позволяя:

  1. Параметризация клиентов с различными запросами: Команда представляет собой объект, который можно хранить, передавать в методы или использовать в коллекциях. Это позволяет создавать универсальные классы, работающие с любыми командами, не зная деталей их реализации.
  2. Постановка запросов в очередь: Команды можно помещать в очередь для выполнения в последующем или в определенном порядке. Подходит для реализации отложенных операций, планировщиков задач или систем логирования.
  3. Предоставление поддержки для отмены операций: Команда может содержать методы для выполнения и отмены действия. Это используется в редакторах текста (отмена/повтор), играх и других приложениях с историей действий.
  4. Логирование изменений: Выполнив команду, можно записать ее в лог. Это полезно для восстановления состояния системы после сбоя или для аудита.
  5. Создание транзакций: Группа команд может быть объединена в одну транзакцию, которая либо выполняется целиком, либо полностью откатывается в случае ошибки.

Структурно паттерн включает следующие компоненты:

  • Command: Интерфейс с методом для выполнения операции (например, execute()).
  • ConcreteCommand: Реализация интерфейса Command, которая связывает приемник с определенным действием. Содержит ссылку на Receiver.
  • Invoker: Класс, который вызывает команду для выполнения. Не знает деталей реализации команды или ее приемника.
  • Receiver: Класс, выполняющий фактическое действие, связанное с командой. Реализует бизнес-логику.
// Интерфейс команды
interface Command {
    void execute();
    // void undo(); // Опционально для поддержки отмены
}

// Конкретная команда
class ConcreteCommand implements Command {
    private final Receiver receiver;
    private final String action; // Пример параметра для приемника

    public ConcreteCommand(Receiver receiver, String action) {
        this.receiver = receiver;
        this.action = action;
    }

    @Override
    public void execute() {
        receiver.performAction(action); // Выполнение действия через приемник
    }
}

// Приемник
class Receiver {
    public void performAction(String action) {
        System.out.println("Performing action: " + action);
    }
}

// Вызывающий
class Invoker {
    private Command command;

    public void setCommand(Command command) {
        this.command = command;
    }

    public void pressButton() {
        if (command != null) {
            command.execute(); // Запуск выполнения команды
        }
    }
}

// Пример использования
public class CommandPatternDemo {
    public static void main(String[] args) {
        Receiver receiver = new Receiver();
        Command command = new ConcreteCommand(receiver, "save file");
        Invoker invoker = new Invoker();
        invoker.setCommand(command);
        invoker.pressButton(); // Вызовет receiver.performAction("save file")
    }
}