Command (Команда)
Шаблон проектирования "Команда" (Command) позволяет инкапсулировать запрос как объект, что позволяет параметризовать клиенты с различными запросами, ставить запросы в очередь или логировать их, а также поддерживать отмену операций. Этот паттерн особенно полезен в ситуациях, когда необходимо отделить отправителя запроса от его получателя.
Основные компоненты паттерна "Команда":
- Команда (Command): интерфейс, который определяет метод для выполнения команды.
- Конкретные команды (Concrete Command): классы, реализующие интерфейс команды и определяющие действия, которые необходимо выполнить.
- Получатель (Receiver): класс, который знает, как выполнить операции, связанные с выполнением команды.
- Invoker: класс, который вызывает команду.
- Клиент (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();
}
}
Объяснение кода:
- Интерфейс
Command
определяет методexecute
, который будет реализован конкретными командами. - Класс
Light
является получателем, который знает, как включать и выключать свет. - Классы
TurnOnLightCommand
иTurnOffLightCommand
реализуют интерфейсCommand
и определяют действия, которые необходимо выполнить (включение и выключение света соответственно). - Класс
RemoteControl
является инвокером, который вызывает команду. Он может изменять команду с помощью методаsetCommand
и выполнять ее с помощью методаpressButton
. - В методе
main
мы создаем экземплярLight
, а затем создаем команды для включения и выключения света. Мы используемRemoteControl
для выполнения этих команд.
Таким образом, паттерн "Команда" позволяет легко добавлять новые команды, не изменяя код инвокера или получателя. Это также упрощает реализацию функциональности отмены и журналирования операций.