Ответ
Паттерн Command инкапсулирует запрос в виде объекта, отделяя объект, инициирующий операцию (Invoker), от объекта, который знает, как ее выполнить (Receiver). Это позволяет параметризовать клиентов различными запросами, ставить их в очередь, логировать или поддерживать отмену операций (undo/redo).
Структура и пример:
// 1. Интерфейс команды
public interface Command {
void execute();
void undo(); // Для поддержки отмены
}
// 2. Конкретная команда
public class LightOnCommand implements Command {
private Light light; // Receiver
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOn();
}
@Override
public void undo() {
light.turnOff();
}
}
// 3. Invoker (например, кнопка в GUI)
public class Button {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void click() {
command.execute();
}
}
Типичные сценарии применения:
- GUI и обработка действий: Кнопки, пункты меню.
- Очереди и планировщики задач: Команды можно ставить в очередь на выполнение в другом потоке или в определенное время.
- Транзакционные операции и отмена: Реализация многошаговых операций с возможностью отката.
- Макрокоманды: Составные команды, выполняющие последовательность других команд.