Что такое совокупный корень? - PullRequest
1 голос
/ 10 октября 2019

Нет, это не вопрос дублирования. У меня есть много источников по этому вопросу, но я все еще чувствую, что не до конца понимаю.

Это информация, которую я имею до сих пор (из разных источников, будь то статьи, видео и т. Д.). .) о том, что такое агрегатный и агрегатный корень:

  • Агрегат - это набор из нескольких объектов-значений \ ссылок и правил сущностей.
  • Агрегат - это всегда модель команды (предназначенная дляизменить бизнес-состояние).
  • Агрегат представляет собой единицу (база данных - потому что изменения будут сохранены), то есть она должна быть согласованной.
  • Агрегированный корень - это интерфейсво внешний мир.
  • Агрегированный корень должен иметь глобально уникальный идентификатор в системе
  • DDD предлагает иметь репозиторий на корень совокупности
  • Простой объект из совокупностине может быть изменен без его AR (Aggregate Root), зная его

Итак, учитывая все это, давайте перейдем к той части, где я запутался:

на на этом сайте написано

Совокупный корень - это интерфейс с внешним миром. Все взаимодействие с Агрегатом происходит через Корень Агрегата. Таким образом, Aggregate Root ДОЛЖЕН иметь глобально уникальный идентификатор в системе. Для других сущностей, которые присутствуют в совокупности, но не являются совокупными корнями, требуется только локально уникальный идентификатор, то есть идентификатор, который уникален в совокупности.

Но тогда в this пример Я вижу, что Aggregate Root реализован статическим классом с именем Transfer, который действует как Aggregate, и статической функцией внутри, называемой TransferedRegistered, которая действует как AR.

Так что вопросы:

  1. Как может случиться, что функция является AR, если для нее должен быть глобальный уникальный идентификатор, а причина в том, что она - функция. что имеет глобальный уникальный идентификатор - это событие домена, которое генерирует эта функция.
  2. Следующий вопрос - как выглядит агрегатный корень в коде? это событие? это сущность, которая возвращается? Является ли это функцией самого класса Aggregate?
  3. В случае, если Событием Домена, которое возвращает функция, является AR (как указано, что он должен иметь этот глобальный уникальный идентификатор), то как мы можем взаимодействовать сэтот агрегат? В первой статье четко указывалось, что все взаимодействие с Агрегатом осуществляется AR, если AR является событием, то мы ничего не можем сделать, кроме как реагировать на него.
  4. Правильно ли говорить, что у агрегата есть два основныхjobs:
    • Примените необходимые изменения на основе полученного им ввода и правил, которые он знает
    • Возвращает необходимые данные, которые необходимо сохранить из AR, и / или которые необходимо получить в событии домена изAR

Пожалуйста, исправьте меня в любом из пунктов маркера в начале, если некоторые / все из них неверны, так или иначе, и не стесняйтесь добавлять большеиз них, если я что-то пропустил!

Спасибо за разъяснения!

Ответы [ 3 ]

1 голос
/ 10 октября 2019

Проще говоря, совокупный корень (AR) - это сущность, которая имеет собственный жизненный цикл. Для меня это самый важный момент. Один AR не может содержать другой AR, но может ссылаться на него с помощью Id или некоторого объекта-значения (VO), содержащего по крайней мере Id указанного AR. Я предпочитаю, чтобы AR содержал только другие VO вместо сущностей (YMMV). С этой целью AR отвечает за последовательность и варианты относительно AR. Каждый VO может иметь свои собственные инварианты, такие как EMailAddress, требующие допустимого формата электронной почты. Даже если бы кто-то назвал сущности содержащихся классов, я назову эту семантику, так как с VO можно было бы сделать то же самое. Репозиторий отвечает за постоянство AR.

Пример реализации, на который вы ссылаетесь, - это не то, что я бы сделал или рекомендовал. Я следовал за некоторыми комментариями, и я тоже, как упоминал один комментатор, предпочел бы использовать доменную службу для выполнения чего-то вроде Transfer между двумя учетными записями. Регистрация передачи не является чем-то, что может быть обязательно разрешено, и, как таковая, доменная служба должна была бы гарантировать действительность передачи. На самом деле, регистрация запроса на перевод, вероятно, была бы Journal в бухгалтерском смысле, так как это мой опыт. Как только журнал будет утвержден, он может попытаться выполнить фактическую передачу.

В какой-то момент моего путешествия в DDD я подумал, что должно быть что-то не так, поскольку не должно быть так сложно понять агрегаты. Существует множество мнений и толкований относительно DDD и совокупностей, поэтому это может привести к путанице. Другой аспект, в ИМХО, заключается в том, что существует значительный объем дизайна, который требует некоторого творчества и который основан на понимании самой области. Творчеству нельзя научить, а дизайн попадает в область молчаливого знания. Популярный пример молчаливого знания - научиться ездить на велосипеде. Теперь мы можем прочитать все, что хотим, о том, как ездить на велосипеде, и это может или не может помочь. Как только мы на велосипеде и научим себя балансировать, тогда мы сможем добиться прогресса. Тогда есть люди, которые заканчивают тем, что делали абсолютно сумасшедшие вещи на велосипеде, и даже если я читаю, как я не думаю, что я попробую:)

Продолжайте практиковаться и моделировать, покаэто начинает иметь смысл или пока вы не почувствуете себя комфортно с моделью. Если я правильно помню, Эрик Эванс упоминает в «Синей книге», что может потребоваться несколько проектов, чтобы приблизить модель к тому, что нам нужно.

1 голос
/ 10 октября 2019

Имейте в виду, что Майк Могосану использует подход с использованием источников событий, но в любом случае (без ES) он очень хорош, чтобы избежать нежелательных артефактов в основных языках ООП.

  1. Какможет ли быть так, что функция является AR, если для нее должен быть глобальный уникальный идентификатор, а причина не в том, что она является функцией. что имеет глобальный уникальный идентификатор, так это событие домена, которое генерирует эта функция.

TransferNumber действует как естественный уникальный идентификатор;в некоторых случаях есть GUID, чтобы избежать необходимости в полном объекте значения.

В памяти компьютера нет уникального состояния идентификатора, потому что это аргумент, но подумайте об этом;почему вы хотите глобальный уникальный идентификатор? Это просто для того, чтобы найти корневой элемент и его дочерние элементы (неуникальный идентификатор) для постоянных целей (найти, изменить или удалить его).

Порядок A имеет 2 строки заказа (1 и 2), в то время как Порядок B имеет 4строки заказа (1,2,3,4);уникальный идентификатор строк заказа представляет собой композицию его идентификатора и идентификатора заказа: A1, B3 и т. д. Он похож на реляционные схемы в реляционных базах данных.

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

Вы можете сделать

var newTransfer = New Transfer(TransferNumber); //newTransfer is now an AG with a global unique ID
var changes = t.RegisterTransfer(Debit debit, Credit credit)
persistence.applyChanges(changes);

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

Следующий вопрос - как выглядит Aggregate Root в коде? это событие? это сущность, которая возвращается? это функция самого класса Aggregate?

Это сама функция. Вы можете прочитать в посте:

AR - это роль, а функция - это реализация.

Агрегат представляет собой единицу работы, то есть он долженбыть последовательным. Вы можете увидеть, как функция выполняет это. Это единица работы, которая поддерживает систему в согласованном состоянии.

В случае, если Событием Домена, которое возвращает функция, является AR (как указано, что он должен иметь этот глобальный уникальный идентификатор), то как мы можем взаимодействовать с этим Агрегатом? В первой статье четко указывалось, что все взаимодействие с Агрегатом осуществляется AR, если AR является событием, то мы ничего не можем сделать, кроме как реагировать на него.

Ответил выше, потому что доменсобытие не является AR.

4 Правильно ли говорить, что у агрегата есть два основных задания: применить необходимые изменения на основе полученных данных и правил, которые он знает, вернуть необходимые данные, которые необходимо сохранить. от AR и / или должны быть подняты в событии домена от AR

Да;опять же, вы можете увидеть, как статическая функция выполняет это.

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

1 голос
/ 10 октября 2019

Мне кажется, я не до конца понимаю.

Это не твоя вина. Литература отстой.

Насколько я могу судить, основные идеи реализации решений с использованием доменного дизайна возникли в мире Java примерно в 2003 году. Таким образом, шаблоны, описанные Эвансом в главах 5 и 6 синего. Книга понималась как объектно-ориентированное (в смысле Java) моделирование предметной области, выполненное правильно.

Глава 6, в которой обсуждается совокупный шаблон, посвящена конкретно управлению жизненным циклом;как вы создаете новые сущности в модели предметной области, как приложение находит нужную сущность для взаимодействия и т. д.

Итак, у нас есть Factories, которые позволяют создавать экземпляры сущностей домена. и Repositories, которые предоставляют абстракцию для извлечения ссылки на сущность домена.

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

Таким образом, агрегированный шаблон является ответом на это;мы организуем согласованные объекты в графы. Что касается изменений (и хранения), граф сущностей становится единым целым, с которым приложению разрешено взаимодействовать.

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

Корень агрегата, являясь точкой входа в агрегат, играет роль грубойДетализированная блокировка, гарантирующая, что все изменения в агрегатных элементах происходят вместе.

Не совсем неправильно думать об этом как о форме инкапсуляции - для приложения агрегат выглядит как единая сущность (корень), а остальная часть сложности совокупности скрыта от глаз.

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

...