DDD моделирование, ссылка на дочерний элемент агрегата root? - PullRequest
0 голосов
/ 04 мая 2020

Я пытаюсь выучить DDD. Я моделирую домен управления собственностью, и я думаю, что у меня есть два контекста (поддомены?): Контекст управления собственностью и резидентный контекст.

Допустим, у меня есть агрегат root Apartment, содержащий Floorplan с и Unit с. Каждый Apartment может иметь много Floorplans, а каждый Floorplan может иметь много Unit s.

public class Apartment : IAggregateRoot // for clarity
{
    public int Id { get; }
    public Address Address { get; set; }
    public ICollection<Floorplan> Floorplans { get; set; }
}

public class Floorplan
{
    public int Id { get; }
    public int ApartmentId { get; set; }
    public string Name { get; set; }
    public int Bedrooms { get; set; }
    public int Bathrooms { get; set; }
    public ICollection<Unit> Units { get; set; }
}

public class Unit
{
    public int Id { get; }
    public int FloorplanId { get; set; }
    public string Number { get; set; }
}

Скажем, в контексте управления собственностью я теперь представляю Resident, которому назначается к Unit. Мои классы Unit и Resident теперь выглядят следующим образом:

public class Unit
{
    public int Id { get; }
    public int FloorplanId { get; set; }
    public string Number { get; set; }
    public ICollection<Resident> Residents { get; set; }
}

public class Resident // in the property management context
{
    public int Id { get; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public void UpdateBalance(...);
}

Теперь мой вопрос: введу ли я Resident в резидентный контекст (это может PayRent() или UpdateProfile() и т. Д. c) они должны иметь отношение 1: 1 с Resident в контексте управления свойствами, но я подумал, что не могу ссылаться на неагрегатную сущность root, не пройдя через Apartment, потому что Resident не может существовать без Apartment.

Я неверно понимаю совокупные корни? Является ли Resident совокупным root в обоих контекстах? Я не уверен, как это можно смоделировать.

Ответы [ 2 ]

0 голосов
/ 05 мая 2020

Теперь у меня вопрос, если я представлю резидента в контексте резидента (который может PayRent () или UpdateProfile () и т. Д. c), они должны иметь отношение 1: 1 с резидентом в контексте управления недвижимостью. , но я подумал, что не могу ссылаться на неагрегатную сущность root, не пройдя полностью через квартиру, потому что резидент не может существовать без квартиры.

Это зависит от вашей архитектуры. По большей части, для меня имеет смысл иметь событие за пределами ваших доменов, которое будет обрабатываться обоими контекстами (протекающим через службу приложения до агрегатов) и будет реагировать, «создавая» соответствующих субъектов (резидент и управляющий недвижимостью клиент?). Обеспечение 1: 1 здесь означало бы, что все события обрабатываются и корректно обрабатываются сбои (это звучит как забавное упражнение).

Все контексты будут иметь границы. Граница будет служить «интерфейсом» контекстов для потребителей. Любая связь между контекстами должна go через этот «интерфейс». В качестве примера: если ваш контекст реализован как микросервис (REST API), вам следует связываться с ним только путем отправки команд HTTP REST. Эта изоляция сохраняет контексты чистыми. Это цель наличия контекстов.

0 голосов
/ 05 мая 2020

Является ли Resident агрегатом root в обоих контекстах?

Нет, это только агрегат root в агрегате Resident в Resident контекст. Когда вы удаляете сущность Apartment, это вызывает удаление всех других сущностей в совокупности, включая сущность Resident (только в контексте Property Management). Но когда Resident покидает блок в квартире, ему не требуется удалять какой-либо другой объект в совокупности Apartment.

Неправильно ли мое понимание агрегированных корней?

Нет, вы правы, что

Я не могу сослаться на неагрегированные root сущность, не проходя через

Но не только агрегат root одного агрегата может ссылаться на root другого агрегата. Не- root объект из одного агрегата может ссылаться на агрегат root из другого агрегата. Взгляните на изображение ниже.

enter image description here

Это изображение взято из курса 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. Я моделирую домен управления собственностью, и я думаю, что у меня есть два контекста (поддомены?)

звучит так, будто вы не уверены в значении терминов контекст и поддомен. Взгляните на изображение ниже; это говорит само за себя:

enter image description here

Это изображение взято из курса Pluralsight Современная архитектура программного обеспечения: модели предметной области, CQRS и события Источник

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...