Skip to content

Command (Команда)

Шаблон проектирования "Команда" (Command) позволяет инкапсулировать запрос как объект, что позволяет параметризовать клиенты с различными запросами, ставить запросы в очередь или логировать их, а также поддерживать отмену операций. Этот паттерн особенно полезен в ситуациях, когда необходимо отделить отправителя запроса от его получателя.

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

  1. Команда (Command): интерфейс, который определяет метод для выполнения команды.
  2. Конкретные команды (Concrete Command): классы, реализующие интерфейс команды и определяющие действия, которые необходимо выполнить.
  3. Получатель (Receiver): класс, который знает, как выполнить операции, связанные с выполнением команды.
  4. Invoker: класс, который вызывает команду.
  5. Клиент (Client): класс, который создает объекты команд и связывает их с получателями.

Пример на Java

Рассмотрим пример, в котором у нас есть система управления светом. Мы создадим команды для включения и выключения света.

// Интерфейс команды
interface Command {
    void execute();
}

// Получатель
class Light {
    public void turnOn() {
        System.out.println("Свет включен");
    }

    public void turnOff() {
        System.out.println("Свет выключен");
    }
}

// Конкретная команда: Включить свет
class TurnOnLightCommand implements Command {
    private Light light;

    public TurnOnLightCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
        light.turnOn();
    }
}

// Конкретная команда: Выключить свет
class TurnOffLightCommand implements Command {
    private Light light;

    public TurnOffLightCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
        light.turnOff();
    }
}

// Инвокер
class RemoteControl {
    private Command command;

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

    public void pressButton() {
        command.execute();
    }
}

// Пример использования
public class CommandPatternExample {
    public static void main(String[] args) {
        Light light = new Light();

        Command turnOn = new TurnOnLightCommand(light);
        Command turnOff = new TurnOffLightCommand(light);

        RemoteControl remote = new RemoteControl();

        // Включаем свет
        remote.setCommand(turnOn);
        remote.pressButton();

        // Выключаем свет
        remote.setCommand(turnOff);
        remote.pressButton();
    }
}

Объяснение кода:

  1. Интерфейс Command определяет метод execute, который будет реализован конкретными командами.
  2. Класс Light является получателем, который знает, как включать и выключать свет.
  3. Классы TurnOnLightCommand и TurnOffLightCommand реализуют интерфейс Command и определяют действия, которые необходимо выполнить (включение и выключение света соответственно).
  4. Класс RemoteControl является инвокером, который вызывает команду. Он может изменять команду с помощью метода setCommand и выполнять ее с помощью метода pressButton.
  5. В методе main мы создаем экземпляр Light, а затем создаем команды для включения и выключения света. Мы используем RemoteControl для выполнения этих команд.

Таким образом, паттерн "Команда" позволяет легко добавлять новые команды, не изменяя код инвокера или получателя. Это также упрощает реализацию функциональности отмены и журналирования операций.