Команда (англ. Command) належить до класу шаблонів поведінки. Команда є деякою дією
та її параметрами. Суть шаблону полягає в тому, щоб відокремити ініціатора та одержувача команди.
Припустимо, у нас є об’єкти Вимикач (Командир) та Лампа (Виконавець). Цей шаблон використовує реалізацію інтерфейсу
CommandInterface
, щоб викликати якийсь метод Виконавця, використовуючи для цього відомий Командирові метод execute()
.
Командир просто знає, що потрібно викликати метод execute()
для обробки команди клієнта,
не розбираючись у деталях реалізації Виконавця. Виконавець відокремлений від команди.
-
CommandInterface.php
<?php namespace DesignPatterns\Behavioral\Command; /** * Interface CommandInterface * @package DesignPatterns\Behavioral\Command */ interface CommandInterface { public function execute(); }
-
CommandRegistry.php
<?php namespace DesignPatterns\Behavioral\Command; use Countable; use RuntimeException; class CommandRegistry implements Countable { /** * @var CommandInterface[] */ private $registry = []; /** * @param string $type * @param CommandInterface $command */ public function add(CommandInterface $command, string $type) { $this->registry[$type] = $command; } /** * @param string $type * @return CommandInterface * @throws RuntimeException */ public function get($type) { if (!isset($this->registry[$type])) { throw new RuntimeException('Cannot find command ' . $type); } return $this->registry[$type]; } public function count() { return count($this->registry); } }
-
Lamp.php
<?php namespace DesignPatterns\Behavioral\Command; class Lamp { public function turnOn() { return 'I\'m bright and cheerful light.'; } public function turnOff() { return 'I am quiet and peaceful shadow.'; } }
-
TurnOffCommand.php
<?php namespace DesignPatterns\Behavioral\Command; class TurnOffCommand implements CommandInterface { /** * @var Lamp */ protected $lamp; /** * @param Lamp $lamp */ public function __construct(Lamp $lamp) { $this->lamp = $lamp; } public function execute() { return $this->lamp->turnOff(); } }
-
TurnOnCommand.php
<?php namespace DesignPatterns\Behavioral\Command; class TurnOnCommand implements CommandInterface { /** * @var Lamp */ protected $lamp; /** * @param Lamp $lamp */ public function __construct(Lamp $lamp) { $this->lamp = $lamp; } public function execute() { return $this->lamp->turnOn(); } }
Test case:
CommandTest.php
<?php
namespace DesignPatterns\Tests\Behavioral\Command;
use DesignPatterns\Behavioral\Command\CommandRegistry;
use DesignPatterns\Behavioral\Command\Lamp;
use DesignPatterns\Behavioral\Command\TurnOffCommand;
use DesignPatterns\Behavioral\Command\TurnOnCommand;
use PHPUnit_Framework_TestCase;
class CommandTest extends PHPUnit_Framework_TestCase
{
/**
* @var CommandRegistry
*/
protected static $registry;
/**
* @var Lamp
*/
protected static $lamp;
public static function setUpBeforeClass(): void
{
self::$registry = new CommandRegistry();
self::$lamp = new Lamp();
}
public function testAddCommandToRegistry()
{
self::$registry->add(new TurnOnCommand(self::$lamp), 'ON');
self::$registry->add(new TurnOffCommand(self::$lamp), 'OFF');
$this->assertEquals(2, self::$registry->count());
}
public function testTurnOnCommand()
{
self::$registry->add(new TurnOnCommand(self::$lamp), 'ON');
$this->assertEquals(self::$lamp->turnOn(), self::$registry->get('ON')->execute());
}
public function testTurnOffCommand()
{
self::$registry->add(new TurnOffCommand(self::$lamp), 'OFF');
$this->assertEquals(self::$lamp->turnOff(), self::$registry->get('OFF')->execute());
}
}