Отправка электронной почты или SMS с использованием CQRS и доменно-ориентированного проектирования

В настоящий момент мы строим новую архитектуру, основанную на принципах CQRS и предметно-ориентированного проектирования.Сейчас мы обсуждаем, как нам поступать с внешним общением. Чтобы сделать вопрос более конкретным, я использую пример отправки SMS-уведомления, когда покупатель создает заказ.

Клиент создает NewOrderCommand, который обрабатывается соответствующим обработчиком команд. Обработчик создает новый объект Order в модели предметной области, который генерирует событие NewcustomerCreatedEvent. Объект сохраняется в хранилище событий, и событие публикуется для всех слушателей.

Пока все хорошо, но теперь вопрос. Куда отправлять SMS-уведомление?

Наш первый инстинкт подсказал нам, что мы должны отправить его, используя прослушиватель событий, который прослушивает NewCustomerCreatedEvent и отправляет сообщение. Проблема с этим подходом заключается в том, что отправка SMS также является частью нашей бизнес-логики. Мы продаем услуги хостинга, поэтому наши клиенты должны иметь возможность видеть все SMS-сообщения, отправленные от их имени. Поскольку отправка сообщения происходит за пределами домена, мы не можем этого сделать.

Итак, мы создали домен SMS, и теперь, когда прослушиватель событий получает событие NewCustomerCreatedEvent, обработчик событий создает новую команду SendSmsMessageCommand, которая будет создавать новый объект SMSMessage в нашем домене, отправляет SMS-уведомление и создает событие SmsSent, которое мы используем для создания представления.

Сначала мы отправляли SMS-сообщение в модели домена, но мы поняли, что это может вызвать некоторые проблемы . Допустим, после отправки SMS что-то происходит (генерируется исключение) и транзакция откатывается. Наш домен полностью поддерживает это, поэтому с данными у нас все в порядке, но SMS-сообщение уже отправлено, поэтому, когда команда будет повторно отправлена, SMS-уведомление будет отправлено снова.

Мы думали об отправке SMS-сообщения о событии SmSSent, но это было бы немного странно, потому что событие говорит, что сообщение уже отправлено, но не отправлено.

Приведенный выше пример подводит нас к вопросу, как работать с внешней связью в CQRS и концепции проектирования, основанной на предметной области? Мы говорим не только об отправке SMS-уведомления, но и об отправке счета-фактуры во внешнюю биллинговую систему и всех других видах связи с внешним миром. Должны ли мы делать это в домене, потому что это бизнес-логика, или мы всегда должны делать это на основе событий в наших обработчиках событий? И если мы это сделаем, допустимо ли использовать события, которые говорят, что сообщение отправлено, когда это еще не сделано?

Надеюсь, вы, ребята, уже справились с этой ситуацией и можете дать нам совет по этому поводу.

19
задан Pepito Fernandez 6 October 2013 в 17:13
поделиться