DDD: чи правильно кореневий агрегат містити посилання на інший кореневий агрегат?


16

Під час дотримання дизайну, керованого доменом (DDD), чи правильно кореневий агрегат містити посилання на внутрішню сутність, яка має бути кореневою сутністю на окремому агрегаті?

Я вважаю, що це не правильно, головним чином через це правило про синю книгу :

Ніщо, що знаходиться поза межами АГРЕГАТИ, не може посилатися на що-небудь всередині, крім кореня ENTITY. Кореневий ENTITY може передавати посилання на внутрішні ENTITIES іншим об'єктам, але ці об'єкти можуть використовувати їх лише тимчасово, і вони не можуть утримувати посилання. Корінь може передати копію VALUE OBJECT іншому об'єкту, і це не має значення, що з ним відбувається, тому що це просто VALUE і більше не матиме жодної асоціації з AGGREGATE.

Якщо кореневий агрегат містить посилання на інший кореневий агрегат, то межа першої порушується і вся концепція агрегату пошкоджена, тому я вважаю, що якщо кореневий агрегат схожий на необхідність утримувати посилання на інший кореневий агрегат, то мені потрібно створити іншу сутність, яка, ймовірно, матиме частину тих же членів, що й інша коренева сутність, але не матиме глобальної ідентичності, як це інше правило в книзі:

Кореневі ENTITIES мають глобальну ідентичність. ЛЕГИСТРИ всередині кордону мають локальну ідентичність, унікальну лише в АГРЕГАТІ.

Я вважаю, що це був би правильний шлях, але оскільки він відчуває себе повторюваним і надлишковим (коли його знімають з контексту DDD, з чистою ООП), я прошу трохи відгуку.


Що ви маєте на увазі під "внутрішньою сутністю (яка є кореневою сутністю на окремому сукупності)"?
Ерік Ейдт

2
FWIW, все може стосуватися сукупної кореневої сутності, оскільки це речі, що мають глобальну ідентичність; незалежно від того, референс сам по собі кореневої сутності чи ні, це не має значення.
Ерік Ейдт

Як сказав Ерік. Також не має значення, чи посилаєтесь ви на нього, використовуючи ідентифікатор або посилання у вашій моделі. Вони обидва перетворять на ідентифікатор на рівні БД, а наявність посилання дає можливість ORM ліниво завантажувати об'єкт на вимогу.
Ейфорія

Відповіді:


21

Можливо, ви занадто інтерпретуєте книгу. Це в основному говорить: нічого поза агрегатом не може містити посилання на що-небудь всередині нього, крім кореня. Тому проведення посилання на корінь є законним. Проведення посилання на корінь не означає, що це частина вашого власного сукупності і що ви можете контролювати його інваріанти. Він зберігає власні інваріанти та самостійність.

Однак,

  • Загальноприйнятою хорошою практикою є посилання на АР, зберігаючи його ідентифікатор, а не повну посилання.
  • Більш сучасні підходи до проектування агрегатів (див. Червону книгу ) пропонують більш чітке розмежування між агрегатами . Бізнес-транзакція повинна змінити лише стан однієї сукупності. Згідно з цим припущенням, необхідність зберігання посилання на інший агрегат має тенденцію до зникнення, оскільки ви не збираєтесь одночасно змінювати 2 агрегати.

чи правильно кореневий агрегат містити посилання на внутрішню сутність, яка, мабуть, є кореневою сутністю на окремому сукупності?

Цього ніколи не буває. Об'єкт цінності може бути частиною кількох агрегатів, але не є об'єктом. Причина полягає в тому, що ніщо тоді не завадить вам ділитися тим самим екземпляром сутності між агрегатами. Скажімо, що екземпляр сутності E належить обом сукупним екземплярам A і B. Оскільки передумова DDD полягає в тому, що сукупність є точкою входу, ви зможете завантажити A, змінити сутність E через неї, весь час мовчки порушуючи інваріанти з Б (що ви не завантажували).

Дивіться відповідь Грега Янг тут: http://domain-driven-design.3010926.n2.nabble.com/Can-an-Entity-be-Shared-across-many-Aggregates-td7579277.html


Дякую Гійом за чітку, лаконічну і проникливу відповідь. Справжній savoir-faire знавців DDD. Це те, що я шукав. Шапо!
Лесейр Валмонт

Я знаю, що це може бути дурне питання, але чи можу я запитати, що holding a referenceв цьому контексті сенс? тому що я розгубився, коли ти це сказав: holding a reference to a root is legitтоді після цього ти сказав:This never happens. A Value Object can be part of multiple Aggregates, but not an Entity. The reason is, nothing would then prevent you from sharing the same entity instance between Aggregates.
Ім'я Donotcare

1
Тримайте посилання = зберігайте її внутрішньо / довговічно, як член класу. Дихотомія тут корінь проти некорінь. Ви можете утримувати кореневу посилання, але не некореневу посилання.
guillaume31

@ guillaume31 велике спасибі, але чи можу я запитати, чи добре зберігати idвнутрішню сутність (не-root) у іншому агрегаті чи це порушує (кореневий чи ні)?
Anyname Donotcare

Що б ви зробили з цим посвідченням? Навіть сховища дають лише коріння, а не внутрішні об'єкти.
guillaume31

1

Ваш сукупний кореневий об'єкт повинен (як правило) мати лише властивості, які є частиною його домену.

Якщо у вас є об’єкт AR з властивістю, якого немає в сукупності, ви негайно стикаєтеся з цим питанням. 'Чому ні?'

Ви могли б додати ідентифікатор іншого об’єкта? Або вставити сховище?

Але це здається, що вам слід додати міждоменну службу, яка посилається на обидва кореневі об'єкти та виконує необхідну логіку


Еване, я думав більше про повторне використання класу між двома різними агрегатами в розумінні OOP, а не про те, щоб доменний сервіс виступав як бізнес-сценарій, який буде виконувати певну роботу з двома різними агрегатами DDD. На закінчення я погоджуюся з вами, мій сукупний корінь повинен мати лише властивості, які є частиною його домену.
Лесаїр Валмонт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.