Що таке сукупний корінь?


447

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

Що стосується шаблону сховища, що таке сукупний корінь?


16
Розглянемо наступні приклади. Ефективний агрегатний дизайн Частина I: Моделювання єдиної сукупності dddcommunity.org/wp-content/uploads/files/pdf_articles/… Частина II: змушування агрегатів працювати разом dddcommunity.org/wp-content/uploads/files/pdf_articles/… Частина III: Отримати інформацію
Ben Vitale

Відповіді:


310

У контексті шаблону репозиторію сукупні корені - це єдині об'єкти, які ваш клієнтський код завантажує із сховища.

Репозиторій інкапсулює доступ до дочірніх об'єктів - з точки зору абонента, він автоматично завантажує їх, або одночасно завантажується корінь, або коли вони фактично потрібні (як при ледачому завантаженні).

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


21
Гіпотетично, якби клієнтському коду потрібен LineItem для якоїсь іншої мети, чи утворював би це окремий сукупність (припускаючи, що будуть залучені інші об'єкти, не пов'язані з об'єктом Порядок)?
Ахмад

20
@Ahmad, інші агрегати можуть називати LineItems даними лише для читання, вони просто не можуть їх змінити . Якщо інші агрегати можуть змінити їх, ви не змогли захистити інваріанти замовлення (а також позиції ").
Jeff Sternal

4
Погляньте на це, наприклад, lostechies.com/blogs/jimmy_bogard/archive/2010/02/23/… . У прикладі Клієнт є інваріантом Порядку, правда? Однак Клієнт може бути ще одним сукупним корінцем? Або я пропускаю тут якесь фундаментальне розуміння?
Ахмад

3
@Jeff Ви сказали, що "вони просто не можуть їх змінити" - це підлягає виконанню, чи це питання конвенції?
Ніл Барнвелл

4
@Neil: Я б застосував це за допомогою будь-яких доступних мовних механізмів - наприклад, створивши незмінний клас для представлення даних.
Jeff Sternal

206

Від Еванса DDD:

АГРЕГАТЕ - це сукупність пов’язаних об'єктів, які ми розглядаємо як одиницю з метою зміни даних. Кожен АГРЕГАТ має корінь і межу. Межа визначає, що знаходиться всередині АГРЕГАТИ. Корінь - це єдиний, специфічний ENTITY, що міститься в АГРЕГАТІ.

І:

Корінь є єдиним членом АГРЕГАТИ, на зовнішніх об'єктах дозволено мати посилання на [.]

Це означає, що сукупні корені - це єдині об'єкти, які можна завантажити з сховища.

Приклад - модель, що містить Customerсутність та Addressсутність. Ми ніколи не звертаємось до Addressсутності безпосередньо із моделі, оскільки це не має сенсу без контексту пов'язаного Customer. Отже, ми могли б сказати, що Customerі Addressразом утворюють сукупність і Customerце сукупний корінь.


57
Оновлення від Еріка Еванса : підкресліть, що сукупні корені - це межі послідовності трансакцій / одночасності та вважають, що сторонні організації не можуть містити посилання на інші дочірні сутності.
Брайан Лоу

3
Тож багатослівність мене назавжди бентежить. Each AGGREGATE has a rootі The root is the only *member* of the AGGREGATE- ця верба означає, що корінь є властивістю сукупності. Але у всіх прикладах все навпаки: корінь містить властивості, які є агрегатами. Ви можете уточнити?
Сінестетик

1
Просто, щоб правильно зрозуміти мою мову, чи Customerвважається клас сукупним коренем чи Customer екземплярами ?
Джо

1
Взагалі кажучи, у парадигмі позиції-замовника-замовника Клієнт буде Кореневим коренем. Екземпляр замовника буде екземпляром цього корінгового кореня. Говорячи про зведений корінь під назвою Клієнт, ви обговорюєте логічну побудову Замовника, що складається з екземпляра замовника. Колекція Клієнтів - це лише колекція.
Ібрагім Маллуф

111

Зведений корінь - це складна назва простої ідеї.


Загальна ідея

Добре розроблена схема класу інкапсулює її внутрішні місця. Точка, через яку ви отримуєте доступ до цієї структури, називається aggregate root.

введіть тут опис зображення

Внутрішнє рішення вашого рішення може бути дуже складним, але користувач цієї ієрархії просто використовуватиме root.doSomethingWhichHasBusinessMeaning().


Приклад

Перевірте цю просту ієрархію класів введіть тут опис зображення

Як ти хочеш їздити на своєму автомобілі? Вибирали краще api

Варіант A (він просто якось працює):

car.ride();

Варіант B (користувач має доступ до інернацій класу):

if(car.getTires().getUsageLevel()< Car.ACCEPTABLE_TIRE_USAGE)
    for (Wheel w: car:getWheels()){
        w.spin();
    }
}

Якщо ви вважаєте, що варіант А краще, то вітайте. Ви отримуєте головну причину позаду aggregate root.


Сукупний корінь інкапсулює декілька класів. ви можете маніпулювати цілою ієрархією лише через основний об'єкт.


17
Мені подобається приклад, але я намагаюся знайти сценарій, за яким Клієнт повинен посилатися на Engine. Здається, двигун повинен бути капсульований за Автомобілем. Чи можете ви трохи розібратися в цьому?
emragins

На мою думку, сам двигун повинен знаходитись у конкретній моделі автомобіля, наприклад, BMW серії 5 з двигуном 3000 куб. При такому моделюванні двигун є компонентом для автомобіля.
Парама Дхарміка

1
@ParamaDharmika впевнений, що ти можеш моделювати це так. Це залежить від того, наскільки «просунутими» автомобілями є ваші клієнти. У базовій моделі він повинен мати доступ до carсукупного кореня. Ви також можете дозволити таку ситуацію, як на малюнку. Правильне рішення залежить від бізнес-моделі застосування. У кожному конкретному випадку це може бути різним.
Marcin Szymczak

1
@MarcinSzymczak правильно, не могла погодитися більше, що рішення залежить від самої моделі домену
Parama Dharmika

Власне, Колесо - це сукупність, яка містить шину (та інші частини). Якщо ваші правила вимагають, щоб до агрегату Wheel можна було отримати доступ лише через автомобільний корінь-агрегат, то двигун також міститься в агрегаті автомобіля Root і не повинен доступ до нього поза автомобілем. Це у царині автомобіля. Власник автомобіля (Замовник) не посилається на двигун, за винятком контексту свого автомобіля.
Ібрагім Маллуф

35

Уявіть, що у вас є комп'ютерна організація, ця організація також не може жити без свого програмного забезпечення та апаратного забезпечення. Вони утворюють Computerсукупність, міні-екосистему для комп’ютерної частини домену.

Зведений корінь - це сукупність материнства всередині сукупності (в нашому випадку Computer), загальною практикою є те, щоб ваш репозитарій працював лише з сутностями, які є агрегованими коренями, і ця сутність відповідає за ініціалізацію інших сутностей.

Розгляньте корінь агрегації як вхідну точку до агрегату.

У коді C #:

public class Computer : IEntity, IAggregateRoot
{
    public Hardware Hardware { get; set; }
    public Software Software { get; set; }
}

public class Hardware : IEntity { }
public class Software : IValueObject { }

public class Repository<T> : IRepository<T> where T : IAggregateRoot {}

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


6
where T : IAggregateRoot- Цей зробив мій день
Крістіан Е.

Формулювання трохи суперечливе, я думаю, і саме це мене бентежить при спробі цього дізнатися. Ви говорите, що Комп'ютер - це сукупність, але потім ви говорите, що корінь буде сутністю материнства ВНУТРИ сукупність. Отже, яка з них є сутністю "материнства" у сукупності в цьому прикладі?
Сінестетик

Привітання з майбутнім !. Що означає хлопець, це те, що Комп'ютер сам по собі є сукупним коренем, тоді як комп'ютер І все, що знаходиться всередині нього, є сукупністю. Або більш чітко: справа сама по собі є сукупним коренем, тоді як весь комп'ютер - це сукупність (колекція всього, що складається з "комп'ютера, наприклад, освітлення RGB, обладнання, джерело живлення, ОС тощо)
Капітан Кенпачі

Техніка IAggregateRoot відображається в документації Microsoft: docs.microsoft.com/en-us/dotnet/architecture/microservices/…
Самуель Даніельсон

16

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

Найпоширеніший приклад - бути Особою. У кожної людини є багато адрес, один або кілька квитанцій про оплату, рахунки-фактури, записи CRM тощо. Це не завжди так, але це 9/10 разів.

Зараз ми працюємо на платформі електронної комерції, і в основному ми маємо два сукупні корені:

  1. Клієнти
  2. Продавці

Клієнти надають контактну інформацію, ми присвоюємо їм транзакції, транзакції отримують позиції тощо.

Продавці продають товари, мають контактних людей, сторінки про нас, спеціальні пропозиції тощо.

Про них опікується відповідно Клієнт та Продавець.


8
Якщо ви дотримуєтесь підходу, що базується на основі баз даних, ви не практикуєте дизайн, керований доменом, ви дотримуєтесь дизайну, керованого даними.
Синестетичний

5
Це форум із запитаннями, на який люди приходять вирішувати проблеми та / або вчитися - Це не я тикав на вас. За визначенням, DDD - це розум більше, ніж будь-що інше, і для багатьох це бентежить, тому я переконався, що коментар був зроблений для тих, хто вивчає DDD, намагаючись полегшити будь-яку потенційну сукупність методологій проектування.
Синестетик

12

Діна:

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

введіть тут опис зображення


1
Отже, якщо ви продавець автомобілів, то Автомобіль буде власним корінним коренем? Тому що у вас може бути багато автомобілів, у яких ще немає клієнта
JorgeeFG

2
@JorgeeFG реальна відповідь - ні в кого немає жодної підказки. Навколо є стільки конфліктної інформації.
Мардокс

3
Дочірні сутності не є сукупностями, вони є лише сутностями, які є членами сукупності, в якій керується сукупним кореневим контролем. "Сукупність" - це логічне угрупування сутностей.
Сінестетик

@JorgeeFG це дійсно залежить від обмеженого контексту, який ти розробляєш. Якщо ви продавець автомобілів, то щось на кшталт Carshop стає корінним корінням, а внизу за ним слід Автомобілі ...
jokab

8

З розірваного зв’язку :

Всередині агрегату є агрегований корінь. Кореневий агрегат є батьківською сутністю для всіх інших об'єктів та об'єктів цінності в агрегаті.

Репозиторій працює на агрегованому корені.

Більше інформації можна знайти тут .


4
Дякую. Це, безумовно, найпоширеніший і розчарувальний розірваний зв’язок, який я постійно перебігав.
Діна

Також формулювання здається зворотним. Як корінь може бути в агрегаті і бути його батьківським одночасно?
Сінестетик

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

8

Сукупність означає збір чогось.
root - як верхній вузол дерева, звідки ми можемо отримати доступ до всього, як <html>вузол у документі веб-сторінки.
Аналогія блогу, Користувач може мати багато дописів, і кожен допис може мати багато коментарів. тож якщо ми забираємо будь-якого користувача, він може діяти як root для доступу до всіх пов’язаних публікацій та подальших коментарів до цих публікацій. Вони всі разом називають збірними або зведеними


1

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


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