DDD: агрегатный корень нуждается в информации от другого агрегатного корня - PullRequest
0 голосов
/ 16 марта 2019

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

На данный момент у меня есть 2 совокупных корня:

  1. User: содержит информацию о пользователе, например display name, linked accounts и profile, которые могутбыть patient profile или care provider profile.Такой профиль пациента содержит информацию, такую ​​как birth date и gender.У меня есть UserRepository, который заботится о получении и спасении пользователей.
  2. Screening: содержит информацию о состоянии здоровья, такую ​​как измерения длины и веса, а также все виды вычисляемой информации, такие как «краткосрочная эволюция»,основанный на этих длинах и весах. У меня есть ScreeningRepository, который заботится о получении и сохранении пользователей.

Таким образом, есть Calculate() метод в Screening, и цель состоит в том, чтобы когдаweight и / или length добавляется к screening, свойства работоспособности, такие как short term evolution, пересчитываются немедленно, так что screening всегда находится в согласованном и правильном состоянии.

Проблема в том, что для этого вычисления также нужны gender и birth date пользователя, которые хранятся в patient profile.

. Таким образом, в основном, корень агрегата screening зависит от корня агрегатаuser. Так что мне интересно, как это сделать ...

  1. Согласно DDD, объединенный корень не должен ссылаться на другой объединенный корень. А также, если бы я сделалuser Имущество screening, тон ScreeningRepository также будет отвечать за дематериализацию пользователя, что, конечно, не является его задачей.

  2. Если screening не имеет ссылки на user, то Calculate()не имеет всей необходимой информации.Таким образом, это означает, что я, вероятно, должен переместить его в доменную службу, которая получает user и screening в качестве входных данных, и выполнить расчет.Хорошо.Но тогда как я могу быть уверен, что при добавлении измерения к проверке срабатывает Calculate?

  3. Другой вариант, о котором я думал, это не делать screening агрегатный корень, и сделайте его просто агрегатом с родительским user.Это также позволяет мне лучше проверить screening, потому что я также могу получить доступ к User.Это решило бы все вопросы о вычислениях, потому что у меня была бы вся информация под рукой, но таким образом, UserRepository будет отвечать также за обработку screening, и мой совокупный корень становится ответственным за users и screenings,

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

Ответы [ 2 ]

1 голос
/ 21 марта 2019

Агрегаты являются наиболее неправильно понятым понятием в DDD.

Пользователь: содержит информацию о пользователе, например отображаемое имя

Это никогда не о данных, это всегда о поведении. Просто совет для практики: на первой итерации сделайте весь ограниченный контекст единым агрегатом, все в одном объекте.

Что будет? Прежде всего, теперь вы можете удовлетворить любой инвариант, который может существовать в ограниченном контексте. Хорошо, но вы скажете, что это безумие, я не могу просто загрузить все в один объект, это будет очень медленно, и никто другой не сможет использовать объект в это время. Правильный! Агрегаты существуют только по одной причине: оптимизация производительности! Вам нужно найти инварианты, которые никогда не влияют друг на друга, чтобы вы могли разделить объект для повышения производительности системы. Как разбить объект?

Кажется, что профиль пациента может быть хорошим кандидатом для совокупного корня с помощью метода Screen (), который инкапсулирует текущую логику скрининга и SetWeightInKg (w) для изменения веса. Профиль поставщика медицинских услуг может быть еще одним агрегатом. Аккаунт еще один. Все просто держат UserId для справки.

Цель состоит в том, чтобы объединить инварианты, которые принадлежат друг другу, в единую совокупность и разделить те, которые не объединяются, для повышения производительности.

1 голос
/ 16 марта 2019

Магии нет.

Если для логики домена для Screening требуются пол и дата рождения, вам необходимо получить копии этих значений в совокупности. Это, в свою очередь, означает, что либо (а) вы передаете значения, либо (б) вы передаете возможность, которая поддерживает запрос значений.

Часто бывает, что агрегат будет кэшировать локальную копию данных, которая "принадлежит" другому агрегату. В этом случае вам может понадобиться разобраться, что произойдет, если эти кэшированные данные должны быть признаны недействительными (например: что произойдет, если мы позже обнаружим ошибку ввода данных при дате рождения?)

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