Что такое паттерн "Команда" (Command)
Команда — поведенческий паттерн проектирования, который инкапсулирует запрос или операцию в отдельный объект. Это позволяет параметризовать объекты с операциями, откладывать или ставить в очередь выполнение команд, а также поддерживать отмену и повтор действий.
Представьте пульт управления, который хранит команды — нажатие кнопки на пульте не знает, что именно происходит, а просто вызывает метод команды. Это отделяет отправителя запроса от объекта, который выполняет действие.
Преимущества паттерна «Команда»
- Разделение отправителя и получателя запроса.
- Возможность легко добавлять новые команды без изменения существующего кода.
- Поддержка отмены, повторения и логирования операций.
- Упрощение построения сложных операций из простых команд.
Пример:
- Команды: Включить свет, выключить свет.
- Получатель: Свет (лампа).
- Отправитель: Пульт управления.
Где применяется паттерн «Команда»?
- Системы с отменой/повтором действий.
- Обработка очередей запросов.
- Реализация транзакций.
- GUI — обработка событий от кнопок, меню.
Пример реализации на JavaScript
// Получатель class Light { on() { console.log("Свет включен"); } off() { console.log("Свет выключен"); } } // Команда включения света class LightOnCommand { constructor(light) { this.light = light; } execute() { this.light.on(); } undo() { this.light.off(); } } // Команда выключения света class LightOffCommand { constructor(light) { this.light = light; } execute() { this.light.off(); } undo() { this.light.on(); } } // Отправитель class RemoteControl { setCommand(command) { this.command = command; } pressButton() { this.command.execute(); } pressUndo() { if (this.command.undo) { this.command.undo(); } } } // Использование const light = new Light(); const lightOn = new LightOnCommand(light); const lightOff = new LightOffCommand(light); const remote = new RemoteControl(); remote.setCommand(lightOn); remote.pressButton(); // Свет включен remote.pressUndo(); // Свет выключен remote.setCommand(lightOff); remote.pressButton(); // Свет выключен remote.pressUndo(); // Свет включен
Когда стоит использовать паттерн «Команда»?
- Нужно инкапсулировать операции и отделить отправителя от получателя.
- Требуется реализовать отмену и повтор действий.
- Необходимо ставить операции в очередь или логировать их.
- Хотите строить сложные действия из простых команд.
Отличие от других паттернов
- В отличие от цепочки обязанностей, команда инкапсулирует запрос, а не передаёт его дальше.
- В отличие от состояния, команда фокусируется на выполнении операций.
Плюсы паттерна
- Упрощает добавление новых операций.
- Позволяет реализовать отмену и повтор.
- Повышает гибкость архитектуры.
- Позволяет реализовать макрокоманды (составные команды).
Минусы паттерна
- Увеличивает количество классов.
- Может усложнить структуру проекта при простых задачах.