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

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

Sobes Copilot

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

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

sobes.tech AI

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

Основные компоненты паттерна:

  • Command: Интерфейс или абстрактный класс, объявляющий метод для выполнения запроса.
  • ConcreteCommand: Классы, реализующие Command, связывающие Receiver с действием. Каждый ConcreteCommand содержит ссылку на Receiver.
  • Invoker: Класс, который инициирует команду. Он содержит ссылку на Command, но не знает деталей операции.
  • Receiver: Класс, который выполняет фактическое действие. ConcreteCommand вызывает методы Receiver.

Пример использования для реализации кнопок управления медиаплеером:

// Receiver
class MediaPlayer {
    public void play() {
        System.out.println("Playing media...");
    }

    public void stop() {
        System.out.println("Stopping media...");
    }
}
// Command
interface MediaCommand {
    void execute();
}
// Concrete Commands
class PlayCommand implements MediaCommand {
    private MediaPlayer player;

    public PlayCommand(MediaPlayer player) {
        this.player = player;
    }

    @Override
    public void execute() {
        player.play();
    }
}

class StopCommand implements MediaCommand {
    private MediaPlayer player;

    public StopCommand(MediaPlayer player) {
        this.player = player;
    }

    @Override
    public void execute() {
        player.stop();
    }
}
// Invoker
class MediaController {
    private MediaCommand command;

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

    public void pressButton() {
        if (command != null) {
            command.execute();
        }
    }
}
// Client Code
class Client {
    public static void main(String[] args) {
        MediaPlayer player = new MediaPlayer();
        PlayCommand playCommand = new PlayCommand(player);
        StopCommand stopCommand = new StopCommand(player);

        MediaController controller = new MediaController();

        controller.setCommand(playCommand);
        controller.pressButton(); // Output: Playing media...

        controller.setCommand(stopCommand);
        controller.pressButton(); // Output: Stopping media...
    }
}

Преимущества:

  • Разделяет отправителя запроса от его выполнения.
  • Позволяет легко добавлять новые команды без изменения Invoker.
  • Поддерживает отмену операций (если реализована).
  • Можно использовать для создания макросов (последовательности команд) и протоколирования операций.