Команда (Command) — шаблон проектирования
29 января 2020
Шаблон предлагает связать инициатора действия и его выполнителя с помощью отдельного класса-команды. Тем самым логика работы с выполнителем действия перемещается из инициатора или клиентского кода внутрь класса-команды. Это позволяет упаковать действие в объект и хранить его, добавлять и извлекать из очереди.
Шаблон состоит из следующих элементов:
Код реализации паттерна на языке PHP. Скачать исходники (ZIP, 3 Кб)
Классы внутри файла:
Результат работы скрипта test.php
Шаблон состоит из следующих элементов:
- Команда (Command) — класс с публичным методом (как правило, метод называется execute()), который напрямую работает с Выполнителем действия;
- Инициатор действия (Invoker) — класс или клиентский код, который инициирует выполнение действия с помощью Команды и её метода execute();
- Выполнитель действия (Receiver) — класс, который непосредственно производит выполнение действия.
Пример задачи: сделать поочерёдную перезагрузку серверных служб (почтовый сервис, база данных, мемкэш).
Код реализации паттерна на языке PHP. Скачать исходники (ZIP, 3 Кб)
commands.classes.php
Содержит классы Команд с объявленным методом execute(), внутри которого выполнение действия (перезагрузка службы) передаётся Выполнителю.Классы внутри файла:
- Command — абстрактный класс с объявленным методом execute(). Является родительским методом для других классов-команд;
- CommandMailServiceReset — класс-команда по перезагрузке почтового сервера. Здесь метод execute() уже определён. Внутри идёт обращение к Выполнителю действия, которым является класс MailService, находящийся в файле mail_service.class.php;
- CommandDBReset — класс-команда по перезагрузке базы данных. Здесь метод execute() тоже определён. Внутри идёт обращение к Выполнителю действия, которым является класс DB, находящийся в файле db.class.php;
- CommandMemcachedReset — класс-команда по перезагрузке системы кэширования Memcached. Метод execute() определён. Внутри идёт обращение к Выполнителю действия, которым является класс CustomMemcached, находящийся в файле custom_memcached.class.php.
<?
/**
* Абстрактный класс команды
*/
abstract class Command
{
/**
* Выполняет команду (действие)
* @return void
*/
abstract public function execute();
}
/**
* Команда по перезагрузке почтового сервера
*/
class CommandMailServiceReset extends Command
{
public function execute()
{
require_once(__DIR__.'/mail_service.class.php');
$mailService = new MailService();
$mailService->reset();
}
}
/**
* Команда по перезагрузке базы данных
*/
class CommandDBReset extends Command
{
public function execute()
{
require_once(__DIR__.'/db.class.php');
$db = new DB();
$db->reset();
}
}
/**
* Команда по перезагрузке кэш-сервиса Memcached
*/
class CommandMemcachedReset extends Command
{
public function execute()
{
require_once(__DIR__.'/custom_memcached.class.php');
$customMemcached = new CustomMemcached();
$customMemcached->reset();
}
}
?>
mail_service.class.php
Класс для работы с почтой. Содержит метод reset() для перезагрузки почтового сервиса.<?
/**
* Почтовый сервис
*/
class MailService
{
/**
* Запускает работу почтового сервиса
*/
public function start()
{
echo 'Почтовый сервис запущен';
echo '<br>';
}
/**
* Перезапускает работу почтового сервиса
*/
public function reset()
{
echo 'Почтовый сервис перезапущен';
echo '<br>';
}
}
?>
db.class.php
Класс для работы базой данных. Содержит метод reset() для перезагрузки БД.<?
/**
* Класс для работьы с БД
*/
class DB
{
/**
* Запускает работу сервера БД
*/
public function start()
{
echo 'БД запущена';
echo '<br>';
}
/**
* Перезапускает работу сервера БД
*/
public function reset()
{
echo 'БД перезапущена';
echo '<br>';
}
}
?>
custom_memcached.class.php
Класс для работы с системой кэширования Memcached. Содержит метод reset() для перезагрузки службы Memcached.<?
/**
* Класс для работьы с кэш-системой Memcached
*/
class CustomMemcached
{
/**
* Запускает работу сервера Memcached
*/
public function start()
{
echo 'Memcached запущен';
echo '<br>';
}
/**
* Перезапускает работу сервера Memcached
*/
public function reset()
{
echo 'Memcached перезапущен';
echo '<br>';
}
}
?>
process_queue.class.php
Содержит класс ProcessQueue, реализующий очередь процессов. Класс используется для добавления команд в очередь с помощью метода addCommand($command). Обход очереди и исполнение процессов осуществляется методом run(). В рамках шаблона класс ProcessQueue является Инициатором действий.<?
//Подключение классов команд
require_once(__DIR__.'/commands.classes.php');
/**
* Класс "Очередь процессов"
*/
class ProcessQueue
{
/**
* Очередь, хранящая объекты команд
*
* @var array
*/
protected $queue;
/**
* Добавляет команду в очередь
* @param command $command - объект команды
* @return bool - в случае успешного добавления команды в очередь метод вернёт 'true', в противном случае вернёт 'false'
*/
public function addCommand($command)
{
if ($command instanceof Command) {
$this->queue[] = $command;
return true;
} else {
return false;
}
}
/**
* Запускает выполнение команд и процессов из очереди
* @return void
*/
public function run()
{
foreach ($this->queue as $z => $process) {
//Выполняем процесс
$process->execute();
//Удаляем процесс из очереди
unset($this->queue[$z]);
}
}
}
?>
test.php
Тестовый скрипт, в котором для перезагрузки серверных служб создаются объекты команд $commandMailServiceReset, $commandDBReset и $commandMemcachedReset. Затем объекты добавляются в очередь процессов $processQueue и далее происходит вызов метода run(), который поочерёдно обходит команды из очереди, вызывая у каждой из них метод execute().<?
//Подключение классов команд
require_once(__DIR__.'/commands.classes.php');
//Подключение класса "Очередь процесов"
require_once(__DIR__.'/process_queue.class.php');
//Создаём объект-команду для перезагрузки почтового сервера
$commandMailServiceReset = new CommandMailServiceReset();
//Создаём объект-команду для перезагрузки БД
$commandDBReset = new CommandDBReset();
//Создаём объект-команду для перезагрузки Memcached
$commandMemcachedReset = new CommandMemcachedReset();
//Добавляем команды в очередь процессов
$processQueue = new ProcessQueue();
$processQueue->addCommand($commandMailServiceReset);
$processQueue->addCommand($commandDBReset);
$processQueue->addCommand($commandMemcachedReset);
$processQueue->run();
?>
Результат работы скрипта test.php
Почтовый сервис перезапущен
БД перезапущена
Memcached перезапущен