Что такое совокупный корень? - PullRequest
398 голосов
/ 24 декабря 2009

Я пытаюсь понять, как правильно использовать шаблон репозитория. Центральная концепция Aggregate Root продолжает появляться. При поиске в Интернете и в Stack Overflow справки о том, что такое совокупный корень, я постоянно нахожу дискуссии о них и мертвые ссылки на страницы, которые должны содержать базовые определения.

В контексте шаблона хранилища, что такое совокупный корень?

Ответы [ 10 ]

275 голосов
/ 24 декабря 2009

В контексте шаблона хранилища агрегированные корни являются единственными объектами, которые ваш клиентский код загружает из хранилища.

Репозиторий инкапсулирует доступ к дочерним объектам - с точки зрения вызывающей стороны он автоматически загружает их либо в тот момент, когда загружается корень, либо когда они действительно необходимы (как при отложенной загрузке).

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

180 голосов
/ 24 декабря 2009

От Эванса DDD:

AGGREGATE - это кластер связанных объектов, которые мы рассматриваем как единое целое с целью изменения данных. Каждый AGGREGATE имеет корень и границу. Граница определяет, что находится внутри АГРЕГАТА. Корень - это отдельная особая сущность, содержащаяся в АГРЕГАТЕ.

И

Корень - единственный член AGGREGATE, которому внешние объекты могут содержать ссылки на [.]

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

Примером является модель, содержащая сущность Customer и сущность Address. Мы никогда не получили бы доступ к сущности Address непосредственно из модели, поскольку это не имеет смысла без контекста связанной Customer. Таким образом, мы можем сказать, что Customer и Address вместе образуют совокупность, а Customer является совокупным корнем.

83 голосов
/ 25 сентября 2015

Совокупный корень - это сложное имя для простой идеи.


Общая идея

Хорошо разработанная диаграмма классов инкапсулирует ее внутренности. Точка, через которую вы получаете доступ к этой структуре, называется aggregate root.

enter image description here

Внутренности вашего решения могут быть очень сложными, но пользователь этой иерархии просто будет использовать root.doSomethingWhichHasBusinessMeaning().


Пример

Проверьте эту простую иерархию классов enter image description here

Как вы хотите ездить на своей машине? Выбрал лучше API

Вариант А (просто как-то работает):

car.ride();

Вариант B (у пользователя есть доступ к инерналам класса):

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

Если вы считаете, что вариант А лучше, тогда поздравляю. Вы получаете основную причину aggregate root.


Совокупный корень инкапсулирует несколько классов. вы можете управлять всей иерархией только через главный объект.

31 голосов
/ 24 декабря 2009

Представьте, что у вас есть объект «Компьютер», этот объект также не может существовать без объекта «Программное обеспечение» и «Оборудование». Они образуют совокупность Computer, мини-экосистему для компьютерной части домена.

Aggregate Root - это сущность материнства внутри агрегата (в нашем случае 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 (без собственной идентификации), рассмотрите его только в качестве примера.

11 голосов
/ 10 сентября 2013

Если вы следуете подходу, основанному на базе данных, то в качестве корневого элемента обычно используется таблица с 1-й стороны отношения 1-много.

Самый распространенный пример - Человек. У каждого человека есть много адресов, один или несколько платежных ведомостей, счета, записи CRM и т. Д. Это не всегда так, но в 9/10 раз больше.

В настоящее время мы работаем над платформой электронной коммерции, и у нас есть два основных корня:

  1. Пользователи
  2. Продавцы

Клиенты предоставляют контактную информацию, мы присваиваем им транзакции, транзакции получают позиции и т. Д.

Продавцы продают товары, имеют контактных лиц, страницы о нас, специальные предложения и т. Д.

Об этом заботятся соответственно Клиент и Продавец.

8 голосов
/ 24 декабря 2009

Из неработающей ссылки :

Внутри Совокупности есть Совокупный Корень. Совокупный корень является родительским объектом для всех других сущностей и объектов значений в совокупности.

Хранилище работает с Совокупным Корнем.

Более подробную информацию также можно найти здесь .

7 голосов
/ 05 декабря 2016

Дин:

В контексте репозитория Совокупный корень является сущностью без родительской сущности. Он содержит ноль, одну или несколько дочерних сущностей, чье существование зависит от Родителя в отношении его идентичности. Это отношение «один ко многим» в репозитории. Эти Дочерние Сущности - простые Совокупности.

enter image description here

3 голосов
/ 16 августа 2016

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

1 голос
/ 16 сентября 2017

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

0 голосов
/ 09 марта 2016

В Erlang нет необходимости проводить различие между агрегатами, как только агрегат состоит из структур данных внутри состояния вместо состава ОО. Смотрите пример: https://github.com/bryanhunter/cqrs-with-erlang/tree/ndc-london

...