Команда (англ. 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 ());
}
}