Проблема с пониманием агрегатов и корней агрегатов в Domain Driven Design (DDD) - PullRequest
0 голосов
/ 18 февраля 2019

Я наткнулся на проблему: «Я не могу разбить свои доменные модели на совокупные корни».

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

С этого момента я хочу кратко описать свой домен.

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

Итак, у нас есть следующие модели:

  1. DocumentType / DocumentTemplate - действует как шаблон, на основе которого создаются конкретные документы.Он имеет отношение один-ко-многим с Document.
  2. DocumentsAttribute - представляет атрибут документа.Он имеет много-много взаимосвязей с DocumentType.
  3. AttributeValue - при создании конкретного документа он смотрит на его тип и создает значения для атрибутов, которые имеют его тип.Связь «многие ко многим» с Document и Attribute.
  4. Document - представляет собой конкретный документ, который создается пользователями.

Существуют другие модели, но я не думаю, что они имеют смысл.

Как вы понимаете, здесь я применяю шаблон Entity Attribute Value (EAV) модели данных.Вы можете увидеть диаграмму , которая показывает отношения в базе данных.

И мои проблемы:

У меня есть много сущностей в моей модели, помимо того, что я описал.

Я думаю, что Document определенно является совокупным корнем в моем Домене.Потому что такие вещи, как ApprovalProcess, который является агрегатным, не могут жить за его пределами.

Вот первый вопрос:

ApprovalProcess состоит из его шагов.Каждый шаг является сущностью, поскольку он изменчив.Шаг имеет свое состояние, которое можно изменить.Состояние ApprvalProcess зависит от его шагов.Здесь у нас есть бизнес-инвариант: «ApprovalProcess может быть утвержден, только если все его шаги утверждены».

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

Я ошибаюсь, что ApprovalProcess является совокупным корнем?Может это просто совокупность?Может ли один совокупный корень существовать в другом как его часть?Означает ли это, что ApprovalProcess является просто агрегатным, поскольку Document отвечает за доступ к его частям?Но когда шаг ApprovalProcess утвержден, Document делегирует операцию ApprovalProcess.

Например:

Document doc = new Document(...);
doc.SendForAooroval(); //ApprovalProcess is created.

doc.ApproveStep(int stepId); // Inside the method Document delegates responsibility for approvement to ApprovalProcess.

Или я должен оставить Document и ApprovalProcess отдельно.Следовательно, Document будет ссылаться на ApprovalProcess по идентификатору.И у нас есть следующий сценарий:

Document doc = documentRepository.Get(docId);
doc.SendForAooroval();// A domain event "DocumentCreatedEvent" is raised.

DocumentCreatedEventHandler:

ApprovalProcess approvalProcess = new ApprovalProcess(event.DocId); // ApprovalProcessCreatedEvent is raised

approvalProcessRepository.Add(approvalProcess);
approvalProcessRepositroy.UnitOfWork.Save(); //commit 

Но если изменяется состояние ApprovalProcess, состояние документа также изменяется.ApprovalProcess одобрен, затем Документ также одобрен.Другое слово ApprovalProcess является частью состояния документа.Только благодаря этому мы можем знать, что Document утвержден.

И самая большая проблема, с которой я сталкиваюсь:

DocumentType также является совокупным корнем.Он состоит из его атрибутов и ApprovalScheme.Я еще не упомянул ApprovalScheme, чтобы сделать мое объяснение максимально простым.ApporvalScheme состоит также из некоторых сущностей.Это просто поток одобрения для DocumentType.ApprovalProcess создается в соответствии с ApprovalScheme для DocumentType, который имеет Document.ApprovalScheme не может существовать без DocumentType.Отношение один к одному.

Документ по идентичности ссылается на свой DocumentType.Это правильно?

В начале этой задачи я думал, что DocumentType должен быть частью Document.

DocumentType имеет много документов, но в моем домене Это не имеет смысла.Он не представляет состояние DocumentType.DocumentType может быть помечен как удаленный, но не может быть удален.

Document и DocumentType - это два разных совокупных корня.Я прав?

Большое вам спасибо, если вы прочитаете это.Большое спасибо за внимание и помощь!Извините за мой ужасный английский.

1 Ответ

0 голосов
/ 20 февраля 2019

Я ошибаюсь, что ApprovalProcess является агрегированным корнем?Может это просто совокупность?Может ли один совокупный корень существовать в другом как его часть?

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

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

Iсм. ApprovalProcess как поток, которому следует документ, а не как сущность.Я не знаю блок-схему процесса, но я предполагаю, что то, что вы называете «шагами», будет «состоянием», которое может иметь документ во время процесса, и у вас будут переходы между шагами, так что сначала при созданииновый документ, он находится на начальном этапе, и в течение срока действия документа он переходит от одного шага к другому, пока не достигнет конечного шага (например, документ утвержден).

Таким образом, объект документа будет иметьповедение, которое меняет свое состояние.

Например, в Java вы можете реализовать шаблон состояний (конечный автомат) с помощью перечислений.

...