Знаете ли вы, что сегодня используется более 4 миллиардов мобильных телефонов ? Здесь, в Австралии, у нас около 11 миллионов человек и более 22 миллионов мобильных телефонов — это в среднем 2 телефона на человека!
Очевидно, что использование мобильного телефона становится все более распространенным. А учитывая повсеместное распространение смартфонов и других мобильных устройств, все больше и больше клиентов теперь предпочитают получать уведомления по SMS, а не по электронной почте. Текстовые сообщения, безусловно, имеют преимущества перед электронной почтой — они короткие, мгновенные, а лучше всего СПАМ незначителен.
Итак, какое это имеет отношение к шаблону команды, который вы спрашиваете? Что ж, давайте посмотрим на воображаемый сценарий.
У компании есть веб-сайт, на котором ежедневно проводятся соревнования на победу. Он имеет базу данных более 250 000 зарегистрированных пользователей, и каждому пользователю отправляется ежедневное кодовое слово, которое они должны либо ввести, либо щелкнуть ссылку, чтобы зарегистрировать свою запись в чертеже. Большинство пользователей решили получать по электронной почте, но значительное число в настоящее время предпочитают получать уведомления по SMS. Вот проблема: как вы отправляете сообщение по двум разным каналам для обеих групп пользователей?
Логическим подходом было бы разделение пользователей на 2 группы, получателей электронной почты и получателей SMS, что подразумевало бы выполнение 2 разных запросов и отправку кодового слова в каждую группу отдельно. Используя шаблон команд, о котором я вам расскажу в этой статье, вы можете отправить сообщение обеим группам пользователей за один процесс.
Очередь сообщений с использованием шаблона команд
Шаблон команды (также иногда называемый шаблоном действия или шаблоном транзакции) — это шаблон проекта, который описывает, как инкапсулировать запрос в виде объекта, чтобы вы могли ставить в очередь или регистрировать клиентов с различными запросами. Чтобы продемонстрировать, как работает шаблон команд, давайте рассмотрим простой пример очереди сообщений. Вот определение класса MessageQueue
:
<?php class MessageQueue { private $queue; public function __construct() { $this->queue = array(); } public function addMessage(IMessage $msg) { $this->queue[] = $msg; } public function execute() { $sendCount = 0; foreach ($this->queue as $msg) { if ($msg->send()) { $sendCount++; } } return $sendCount; } }
В очереди сообщений представлены два метода — метод addMessage()
который добавляет объекты сообщений в очередь, и метод execute()
который обрабатывает каждое сообщение в очереди. В этом примере метод addMessage()
просто добавляет сообщения во внутренний массив $queue
, а метод execute()
просматривает элементы в $queue
и вызывает метод send()
для каждого объекта сообщения.
Шаблон команды ставит в очередь каждый запрос для последующей обработки; Фактический механизм отправки электронной почты или SMS будет реализован в методе send()
объекта. MessageQueue
не нужно знать, как обрабатывать запрос, так как это будет ответственностью запрашивающего объекта. Чтобы обеспечить доступность метода send()
, объекты сообщений должны реализовывать интерфейс IMessage
.
<?php interface IMessage { public function send(); }
Каждый объект сообщения реализует интерфейс IMessage
и предоставляет собственную реализацию метода send()
.
<?php class DailyAlertEmail implements IMessage { ... public function send() { // actual code here to send email // ... echo "Sending message via emailn"; } } class DailyAlertSMS implements IMessage { ... public function send() { // actual code here to send the SMS // ... echo "Sending message via SMSn"; } }
В сообщении DailyAlertEmail
реализован метод send()
для отправки кодового слова в виде электронного письма, а в DailyAlertSMS
сообщения DailyAlertSMS
реализован метод send()
для отправки сообщения в виде SMS.
Затем, чтобы отправить получателям SMS и электронной почты сообщение, вы запросите базу данных об их предпочтении связи, создадите экземпляр подходящего объекта IMessage
и добавите его в очередь сообщений, а затем вызовите метод execute()
очереди. Между прочим, создание правильного объекта IMessage
для пользователя было бы хорошей возможностью использовать шаблон проектирования Factory Method !
<?php // create a new queue $msgQueue = new MessageQueue(); $result = $db->query("SELECT * FROM customers"); while ($customer = $result->fetch(PDO::FETCH_ASSOC)) { // factory creates a DailyAlertSMS or DailyAlertEmail object // based on the user's preferences $msg = MessageFactory::build($customer, $codeword); // add the message object to the queue $msgQueue->addMessage($msg); } // send to all customers now $msgQueue->execute();
Используя шаблон команд, вы можете извлечь всех клиентов из базы данных, создать экземпляры соответствующих реализаций IMessage
независимо от коммуникационных предпочтений клиентов и обработать их один раз, вместо того, чтобы сначала запрашивать базу данных у всех клиентов SMS и обрабатывать их, а затем повторять процесс для клиентов электронной почты.
Имейте в виду, что это только основной пример; В реальных приложениях было бы предпочтительным пакетировать SMS и сообщения электронной почты и отправлять их периодически в течение дня, в идеале в качестве фонового процесса. С некоторыми незначительными изменениями вы можете преобразовать это в «отложенную» очередь сообщений, запускаемую как задачу cron, и использовать базу данных для отслеживания хода процесса.
Резюме
Как видите, шаблон команд хорошо подходит для следующих ситуаций:
- Вы хотите иметь возможность параметризовать объекты с помощью действия, которое нужно выполнить.
- Вам необходимо указывать, ставить в очередь и выполнять запросы в разное время.
- Когда набор изменений в данных необходимо инкапсулировать как одно действие (т. Е. Транзакцию).
В этом уроке я показал вам, как шаблон команд может быть полезным шаблоном проектирования для реализации очереди команд, где запросы могут быть поставлены в очередь для последовательной обработки, в то же время отделяя фактическую реализацию выполнения от самой очереди.