Аналогія
Ви прийшли до ресторану. Ви (Client) просите офіціанта (Invoker) принести блюда (Command). Офіціант перенаправляє запит шеф-кухареві (Receiver), який знає, що і як готувати. Інший приклад: ви (Client) включаєте (Command) телевізор (Receiver) за допомогою пульта (Invoker).
Стисло
Шаблон “Команда” дозволяє інкапсулювати дії в об’єкти. Ключова ідея – надати кошти відділення клієнта від отримувача.
Вікіпедія
У шаблоні «Команда» об’єкт використовується для інкапсуляції всієї інформації, яка потрібна на виконання дії чи його ініціювання пізніше. Інформація включає ім’я методу; об’єкт, який володіє способом; значення параметрів методу
Приклад
Спочатку зробимо одержувача, що містить реалізації кожної дії, яка може бути виконана.
// Receiver
class Bulb
{
public function turnOn()
{
echo "Bulb has been lit";
}
public function turnOff()
{
echo "Darkness!";
}
}
Тепер зробимо інтерфейс, який реалізовуватиме кожна команда. Також зробимо набір команд.
interface Command
{
public function execute();
public function undo();
public function redo();
}
// Command
class TurnOn implements Command
{
protected $bulb;
public function __construct(Bulb $bulb)
{
$this->bulb = $bulb;
}
public function execute()
{
$this->bulb->turnOn();
}
public function undo()
{
$this->bulb->turnOff();
}
public function redo()
{
$this->execute();
}
}
class TurnOff implements Command
{
protected $bulb;
public function __construct(Bulb $bulb)
{
$this->bulb = $bulb;
}
public function execute()
{
$this->bulb->turnOff();
}
public function undo()
{
$this->bulb->turnOn();
}
public function redo()
{
$this->execute();
}
}
Тепер зробимо викликаючого Invoker, з яким взаємодіятиме клієнт для обробки команд.
// Invoker
class RemoteControl
{
public function submit(Command $command)
{
$command->execute();
}
}
Подивимося, як це може використовувати клієнт:
$ bulb = New Bulb ();
$turnOn = New TurnOn($bulb);
$turnOff = New TurnOff($bulb);
$ remote = new RemoteControl();
$remote->submit($turnOn); // Лампочка спалахнула!
$remote->submit($turnOff); // Темрява!
Шаблон “Команда” можна використовувати і для реалізації системи на основі транзакцій. Тобто системи, де ви зберігаєте історію команд у міру їх виконання. Якщо остання команда виконана успішно, все добре. Інакше система ітерує з історії та робить undo для всіх виконаних команд.