Возможно, вы захотите отобразить уровень запасов на веб-странице, или вы можете отобразить номер издания инвентаря на складе (представьте, что ваш инвентарь - книги, журналы и т. Д.). Эта информация поступает из домена инвентаризации.
Главное, на что следует обратить внимание, это то, что вы говорите о представлении, то есть о том, что использование устаревших данных допустимо.
При этом вам не нужно взаимодействовать с агрегатами (которые несут ответственность за предотвращение нарушения изменений бизнес-инварианта), а с представлением недавней копии состояния агрегата.
Поэтому я обычно ожидаю, что запрос будет выполнен по каталогу продуктов, а другой - по инвентаризации, и что-то, что объединит их в DTO, которые вам понадобятся для поддержки представления.
Загрузить как домен продукта, так и агрегаты домена инвентаризации?
Так что это близко . Нам не нужно загружать агрегаты, потому что мы не собираемся ничего менять. Но нам нужно их состояние; чтобы мы могли загрузить это. Тем не менее, я обычно ожидаю, что два домена будут работать в разных процессах. Поэтому мы будем звонить обоим, а не загружать оба.
Будете ли вы хранить некоторые свойства в своей сущности домена Product для количества на складе и издания на складе, а затем использовать события домена для обновления их при обновлении сущности Inventory?
«Не пересекать потоки. Это было бы плохо».
Использование событий для координации информации в разных контекстах домена: отличная идея. Вытеснение концепций, принадлежащих одному домену, в другой: противоположность великой идеи, за исключением большей.
Вы хотите сохранить домены в чистоте. Эти приложения , которые взаимодействуют с доменами, это не так важно. Так, например, для приложения Inventory целесообразно вызвать службу в приложении продукта, чтобы запросить некоторые специфические для продукта концепции для добавления в представление. Или наоборот.
Я не знаю ни одной причины, по которой одно приложение должно быть ограничено одним доменом. Пока существует единый источник правды, вы можете распределять транзакции любым удобным вам способом.
Но просто чтобы обдумать это, в приведенном выше примере мы получим потенциально 2 таблицы БД для каталога товаров и инвентаря товаров. Теперь мы используем тот же идентификатор в них, как и тот же продукт.
Это был бы легкий путь. В более широком смысле вы используете один и тот же идентификатор, потому что сущность реального мира одинакова; два разных ограниченных контекста моделируют эту сущность по-разному, но модель не является сущностью реального мира.
Когда это не сработает, тогда вам понадобится какой-то запрос, чтобы восполнить пробел. Я думаю, что наиболее распространенным вариантом этого является то, что более новый объект сохраняет идентификатор более старого объекта. Вы увидите это и в рамках одной БК: заявители, когда они будут одобрены, станут клиентами. Это другой агрегат (состояние, связанное с клиентом, подчиняется инварианту, отличному от состояния кандидата); поэтому, если ваш уровень персистентности использует потоки событий, потоку для нового агрегата потребуется другой идентификатор. Так что где-то будет состояние, в котором говорится, что «этот заявитель стал этим клиентом».
Или мы могли бы использовать 1 таблицу и 1 строку таблицы для данных и просто отобразить соответствующие данные на совокупные свойства?
YIKES! Нет, не делай этого. Вы добавляете конфликт транзакций без какой-либо деловой причины для этого.
Я думаю, что ваш вопрос действительно требует 2 ортогональных набора опций -
Вы загружаете два объекта и представляете их данные вместе, или вы загружаете 1 объект, который содержит все, что вы хотите?
Вы используете агрегаты для отображения материала или что-то еще?
Если вы верите в подход CQRS, то получается, что агрегаты могут быть не лучшим выбором для чтения. Каждый раз, когда вы загружаете агрегат, независимо от того, отображаете ли вы его данные или изменяете их, вы добавляете параллелизм и конкуренцию в вашу систему. Кроме того, агрегаты могут быть более объемными и загружаться медленнее, чем при использовании специальных моделей чтения, специально предназначенных для отображения.
Решение а) от вашего Q, похоже, подвержено множеству этих ловушек. Вариант б) может быть действительным, но я бы использовал его, только если данные из
InventoryManagement
BC необходимы для принудительного применения инвариантов при мутированииProduct
агрегата. Лучше, если агрегат содержит все данные, необходимые для проверки своих бизнес-правил после модификации, но на стороне чтения они могут находиться где угодно.Что касается данных, общая рекомендация состоит в том, чтобы предоставить ограниченным контекстам свою собственную базу данных (по причинам развертывания и SoC). Возможно, вам придется использовать одинаковые идентификаторы, если вы хотите сопоставить продукты между двумя BC.
О взаимодействиях между BC вы также можете посмотреть на /programming/16713041/communicating-between-two-bounded-contexts-in-ddd
источник
DDD предназначен для приложений, где бизнес-логика сложна. «напечатать что-нибудь» не является сложной бизнес-логикой. На самом деле это совсем не бизнес-логика.
Если бизнес-логике в одном контексте требуется некоторая информация для правильной обработки некоторого варианта использования, то эта информация является частью этого контекста. Таким образом, идея о том, что одному ограниченному контексту может понадобиться информация, доступная в другом ограниченном контексте, не имеет смысла, потому что ограниченный контекст содержит всю необходимую информацию.
источник
С моей точки зрения, существуют различные определения «продукта» - каждый ограничивающий контекст имеет свое собственное определение «продукта»: домен:
Вдобавок к этому я бы добавил дополнительный Shop-Bounding-Context с его собственным определением продукта (соответствующая комбинация доменов продукта других Bounding-Contextxts).
Магазин-продукт будет иметь «изображение и текст описания» из содержимого и наличия в «Инвентаризации», но не «продавец продукта» из инвентаря.
Этот дополнительный ограничивающий контекст магазина зависит от содержимого ограничивающего контекста, инвентаря, цены
источник