Является ли Resident
агрегатом root в обоих контекстах?
Нет, это только агрегат root в агрегате Resident
в Resident
контекст. Когда вы удаляете сущность Apartment
, это вызывает удаление всех других сущностей в совокупности, включая сущность Resident
(только в контексте Property Management
). Но когда Resident
покидает блок в квартире, ему не требуется удалять какой-либо другой объект в совокупности Apartment
.
Неправильно ли мое понимание агрегированных корней?
Нет, вы правы, что
Я не могу сослаться на неагрегированные root сущность, не проходя через
Но не только агрегат root одного агрегата может ссылаться на root другого агрегата. Не- root объект из одного агрегата может ссылаться на агрегат root из другого агрегата. Взгляните на изображение ниже.
Это изображение взято из курса Pluralsight Домен-ориентированный дизайн на практике
Для определения root сущность в совокупности использует этот принцип, который уже описан в моем ответе выше (цитата взята из книги Applied Akka Patterns ):
Агрегаты и связанные с ними корни - сложное понятие. Может быть сложно определить, что является агрегатом в вашей системе, или, что более важно, что такое агрегат root. Как правило, совокупные корни - это части системы верхнего уровня. Все ваши взаимодействия с системой так или иначе будут связаны с совокупным значением root (за некоторыми исключениями). Так как же определить ваши совокупные корни? Одно простое правило - подумать об удалении. Если вы выберете конкретную c Entity в системе и удалите ее, удалит ли это другие Entity в системе? Если ваша система состоит из людей, у которых есть адреса, и вы удаляете адрес, удаляет ли она другие части системы? В этом случае, вероятно, нет. С другой стороны, если вы удалите человека из системы, есть большая вероятность, что вам больше не нужно хранить адрес этого человека, поэтому в этом случае человек может агрегировать адрес.
Теперь ваш вопрос о том, как это должно быть смоделировано:
Мой вопрос теперь в том, введу ли я Resident
в контекст Resident
(который может PayRent () или UpdateProfile () , et c) они должны иметь отношение 1: 1 с Resident
в контексте Property Management
, но я думал, что не могу ссылаться на неагрегатную сущность root, не пройдя полностью через Apartment
, потому что Resident
не может существовать без Apartment
.
На мой взгляд, Resident
в контексте Property Management
следует представлять как объект, поскольку у него есть идентификатор (например, паспорт, водительское удостоверение), и объект должен иметь только те свойства объекта Resident
в контексте Resident
, которые будут использоваться в контексте Property Management
.
Я бы предложил пересмотреть имя Resident
для контекста Resident
. Когда вы храните информацию о человеке, но этот человек в настоящее время не проживает в квартире, он \ она технически не Resident
этой квартиры, это просто человек, который планирует \ планирует жить, в настоящее время живет или проживал в квартира. Я думаю, что лучшее название для того, что вы называете контекстом Resident
, - Person
.
Для связи между контекстами используйте события интеграции (не путайте их с событиями домена):
События домена по сравнению с событиями интеграции
Семантически, события домена и интеграции - это одно и то же: уведомления о том, что только что произошло. Однако их реализация должна быть разной. События домена - это просто сообщения, отправленные диспетчеру событий домена, который может быть реализован как посредник в памяти на основе контейнера IoC или любого другого метода.
С другой стороны, целью событий интеграции является распространение зафиксированных транзакций и обновлений на дополнительные подсистемы, будь то другие микросервисы, ограниченные контексты или даже внешние приложения. Следовательно, они должны происходить только в том случае, если объект успешно сохраняется, в противном случае создается впечатление, что вся операция никогда не выполнялась.
Как упоминалось ранее, события интеграции должны быть основаны на асинхронной связи между несколькими микросервисами (другими ограниченными контекстами) или даже внешние системы / приложения.
Таким образом, интерфейс шины событий нуждается в некоторой инфраструктуре, которая обеспечивает межпроцессную и распределенную связь между потенциально удаленными службами. Он может быть основан на коммерческой служебной шине, очередях, общей базе данных, используемой в качестве почтового ящика, или любой другой распределенной и, в идеале, системе обмена сообщениями на основе pu sh.
События домена: дизайн и реализация
Я заметил, что эта часть вашего вопроса:
Я пытаюсь выучить DDD. Я моделирую домен управления собственностью, и я думаю, что у меня есть два контекста (поддомены?)
звучит так, будто вы не уверены в значении терминов контекст и поддомен. Взгляните на изображение ниже; это говорит само за себя:
Это изображение взято из курса Pluralsight Современная архитектура программного обеспечения: модели предметной области, CQRS и события Источник
Поддомен представляет собой часть проблемы, тогда как ограниченный контекст представляет собой часть решения, которое решает проблему. Каждая подобласть обычно покрывается одним ограниченным контекстом. В некоторых случаях один субдомен может соответствовать более чем одному ограниченному контексту, например, когда у вас есть субдомен со старыми требованиями и ограниченным контекстом, который уже реализовал эти требования, а позже у вас есть новые требования, и вы не хотите чтобы по какой-то причине изменить существующий ограниченный контекст, тогда вы можете ввести новый ограниченный контекст для этих новых требований. Этот новый контекст должен быть отделен от старого с помощью антикоррупционного уровня.