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