Статья
Шаблон проектирования "Команда"

Шаблон проектирования "Команда"

3 апреля 2020

Относится к поведенческим шаблонам.

Шаблон представляет интерфейс для пользователя, но в отличие от фасада, который нужен для упрощения интерфейса, шаблон "Команда" создает классы-команды, которые реализуют общий интерфейс и отделяет инициатора команды от получателя.

Плюсы:
- убирает зависимость между инициаторами и исполнителями команды;
- позволяют скрыть сложность выполнения команд в классах команд

Пример на PHP

class SecuritySystem
{
    public function enableHallSecuritySystem()
    {
    }

    public function enableBathroomSecuritySystem()
    {
    }

    public function enableDiningRoomSecuritySystem()
    {
    }

    public function disableLobbySecuritySystem()
    {
    }

    public function disableHallSecuritySystem()
    {
    }

    public function disableBathroomSecuritySystem()
    {
    }

    public function disableDiningRoomSecuritySystem()
    {
    }

    public function disableLobbySecuritySystem()
    {
    }
}

 

Сформируем набор команд:

interface Command
{
    public function execute(): void;
}

class TurnOn implements Command
{
    protected SecuritySystem $system;

    public function __construct(SecuritySystem $system)
    {
        $this->system = $system;
    }

    public function execute(): void
    {
        $this->system->enableHallSecuritySystem();
        $this->system->enableBathroomSecuritySystem();
        $this->system->enableDiningRoomSecuritySystem();
        $this->system->enableLobbySecuritySystem();
    }
}

class TurnOff implements Command
{
    protected SecuritySystem $system;

    public function __construct(SecuritySystem $system)
    {
        $this->system = $system;
    }

    public function execute(): void
    {
        $this->system->disableHallSecuritySystem();
        $this->system->disableBathroomSecuritySystem();
        $this->system->disableDiningRoomSecuritySystem();
        $this->system->disableLobbySecuritySystem();
    }
}

 

Создаем класс-получателя команд:

class Control
{
    public function submit(Command $command)
    {
        $command->execute();
    }
}

 

Использование:

$system = new SecuritySystem();

$turnOn = new TurnOn($system);
$turnOff = new TurnOff($system);

$control = new Control();
$control->submit($turnOn);
$control->submit($turnOff);


Пример на Go

package main

type SecuritySystem struct {
}

func (s *SecuritySystem) EnableHallSecuritySystem() {
}

func (s *SecuritySystem) EnableBathroomSecuritySystem() {
}

func (s *SecuritySystem) EnableDiningRoomSecuritySystem() {
}

func (s *SecuritySystem) EnableLobbySecuritySystem() {
}

func (s *SecuritySystem) DisableHallSecuritySystem() {
}

func (s *SecuritySystem) DisableBathroomSecuritySystem() {
}

func (s *SecuritySystem) DisableDiningRoomSecuritySystem() {
}

func (s *SecuritySystem) DisableLobbySecuritySystem() {
}

type ICommand interface {
   Execute()
}

type TurnOn struct {
   sys SecuritySystem
}

type TurnOff struct {
   sys SecuritySystem
}

func (c *TurnOn) Execute() {
   c.sys.EnableBathroomSecuritySystem()
   c.sys.EnableHallSecuritySystem()
   c.sys.EnableLobbySecuritySystem()
   c.sys.EnableDiningRoomSecuritySystem()
}

func (c *TurnOff) Execute() {
   c.sys.DisableBathroomSecuritySystem()
   c.sys.DisableHallSecuritySystem()
   c.sys.DisableLobbySecuritySystem()
   c.sys.DisableDiningRoomSecuritySystem()
}

type Control struct {
   command ICommand
}

func (c *Control) Submit() {
   c.command.Execute()
}

func main() {
   system := SecuritySystem{}
   turnOnCommand := TurnOn{sys: system}
   control := Control{command: &turnOnCommand}
   control.Submit()
}


Источники:
http://designpatternsphp.readthedocs.io/ru/latest/Behavioral/Command/README.html
https://habrahabr.ru/company/mailru/blog/325492/