Извлечение потенциально необходимых данных из репозитория — DDD

#rest #domain-driven-design

#rest #дизайн, управляемый доменом

Вопрос:

У нас есть (примерно) следующая архитектура:

  1. Служба приложений выполняет инфраструктурную работу — извлекает данные из репозиториев, которые скрыты за интерфейсами.
  2. Создается граф объектов и передается соответствующей службе домена.
  3. Служба домена выполняет это и вызывает соответствующие события.
  4. События обрабатываются в различных службах приложений, которые выполняют некоторые постоянные операции (изменение репозиториев, отправка электронных писем и т.д.).

Однако. Доменная служба (3) стала настолько сложной, что ей требуются данные из разных внешних API только в том случае, если выполняются определенные условия. Например, если продукт X относится к типу Car, нам нужно узнать цену на эту модель автомобиля из какого-либо внешнего CatalogService (пример изобретен), скрытого за ICatalogService. Эта операция является потенциально дорогостоящей (вызов REST).

Как нам это сделать?

A. Выполняем ли мы предварительную выборку всех данных в службе приложений, перечисленных как (1), даже если они нам могут не понадобиться? Внедряем ли мы интерфейс ICatalogService в данную доменную службу и извлекаем ли данные только при необходимости? Последнее решение может создать проблемы с производительностью, если какой-либо другой клиент доменной службы повторно вызывает эту доменную службу, не зная, что внутри нее скрыт вызов REST.

Или мы просто неправильно определили модель предметной области?

Этот вопрос связан с дизайном, управляемым доменом.

Ответ №1:

Как нам это сделать?

Существует два распространенных шаблона.

Один из них заключается в передаче возможности выполнения запроса в модель предметной области, позволяя модели самой извлекать информацию, когда это необходимо. Обычно это будет выглядеть как определение интерфейса / контракта, который будет использоваться моделью предметной области, но реализован на уровнях приложения / инфраструктуры.

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

Если вы проявите немного воображения, у вас уже есть конечный автомат примерно такого типа; поскольку код вашего приложения уже координирует перемещение входных данных в репозиторий и модель предметной области. Разница, конечно, в том, что существующий «конечный автомат» достаточно прост и линейен, так что может быть неочевидно, что конечный автомат вообще присутствует.

как именно вы бы сигнализировали о прикладном уровне?

Простые запросы; иными словами, код приложения извлекает необходимую ему информацию из модели предметной области и использует эту информацию для вычисления следующего действия. Когда действие завершено, код приложения отправляет информацию в модель предметной области.

Комментарии:

1. В настоящее время мы используем подход с возможностью. Мне любопытно узнать о 2-м подходе, как именно вы бы сигнализировали о прикладном уровне?

Ответ №2:

Недостаточно информации, чтобы дать вам целевой хороший совет. Я подозреваю, что вам нужно реорганизовать ваши домены на дополнительные поддомены. Похоже, что на вашу доменную службу возложено гораздо больше ответственности, чем на 1. Упростите обслуживание.

Кроме того, если у вас есть длительно выполняющаяся задача, такая как вызов службы, которая занимает много времени, вам нужно ее спроектировать. Самый гибкий дизайн не заставит потребителя ждать. Он немедленно вернется пользователю с каким-либо результатом, даже если это просто периодическое обновление статуса.