Управляемый доменом дизайн: когда нужно создавать совокупный корень? - PullRequest
5 голосов
/ 01 октября 2009

Я впервые пытаюсь внедрить DDD с проектом ASP.NET MVC, и я борюсь с несколькими вещами.

У меня есть 2 связанных лица, Компания и Поставщик. Сначала я думал, что компания является совокупным корнем, а поставщик является ценным объектом для компании. Так что у меня есть репозиторий для компании и нет для поставщика.

Но поскольку я начал создавать свое приложение, мне потребовался отдельный список, создание и обновление форм для Поставщика. Список был прост, я мог позвонить Company.Suppliers, и создать было ужасно, я мог сделать Company.Suppliers.Add (поставщик), но обновление вызывает у меня головную боль. Поскольку мне нужна только одна сущность, и я не могу точно вставить ее в память между формами, мне в конечном итоге понадобилось переосмыслить компанию и всех поставщиков и найти ту, которая мне была необходима, чтобы привязать к ней и снова модифицировать и сохранить ее. вернуться к БД.

Мне действительно нужно было сделать GetOne, если у меня был репозиторий для поставщика. Я мог бы добавить некоторые обходные пути, добавив GetOneSupplier в свою компанию или CompanyRepository, но это выглядит неуклюже.

Итак, мне действительно интересно, действительно ли это объект Value, а не сам объект домена.

tldr;

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

Ответы [ 2 ]

35 голосов
/ 01 октября 2009

Исходя из вашей терминологии, я предполагаю, что вы выполняете DDD по книге Эрика Эванса. Похоже, вы уже определили проблему с вашим начальным моделированием, и вы правы.

Вы упоминаете, что думали о поставщике как Value Object ... Я полагаю, что это не так. A Value Object - это то, что в первую очередь определяется его свойствами. Например, дата «30 сентября 2009 года» является объектом значения. Зачем? Потому что все экземпляры даты с другим комбо месяц / день / год разные даты. Все экземпляры даты с одинаковым списком месяц / день / год считаются идентичными. Мы бы никогда не стали спорить о том, чтобы заменить мои «30 сентября 2009 года» на ваши, потому что они одинаковы: -)

С другой стороны, Entity в первую очередь идентифицируется по его «идентификатору». Например, банковские счета имеют идентификаторы - все они имеют номера счетов. Если в банке есть два счета, каждый на 500 долларов, если номера их счетов разные, то и они тоже. Их свойства (в данном примере их баланс) не идентифицируют их и не подразумевают равенство. Бьюсь об заклад, мы будем спорить по поводу обмена банковских счетов, даже если их остатки были одинаковыми: -)

Итак, в вашем примере я бы назвал поставщика Entity, так как я бы предположил, что каждый поставщик в первую очередь идентифицируется по своему идентификатору, а не по свойствам. Моя собственная компания делится своим именем с двумя другими в мире - но мы не все взаимозаменяемы.

Я думаю, что ваше предположение о том, что если вам нужны представления для CRUDing объекта, то это Entity, вероятно, справедливо в качестве практического правила, но вы должны сосредоточиться больше на том, что отличает один объект от других: свойства или ID.

Теперь, что касается Aggregate Root, вы хотите сосредоточиться на жизненном цикле и управлении доступом к объектам. Считайте, что у меня есть блог с множеством постов, в каждом из которых есть много комментариев - где находится Aggregate Root? Начнем с комментариев. Имеет ли смысл оставлять комментарий без поста? Не могли бы вы создать комментарий, а затем найти сообщение и прикрепить его к нему? Если вы удалите сообщение, будете ли вы оставлять его комментарии? Я предлагаю пост Aggregate Root с одним «листком» - комментариями. Теперь рассмотрим сам блог - его отношения с постами аналогичны отношениям между постами и комментариями. Это тоже, на мой взгляд, Aggregate Root с одним "листком" - сообщения.

Итак, в вашем примере, существует ли тесная связь между компанией и поставщиком, при которой, если вы удалите компанию (я знаю ... у вас, вероятно, есть только один экземпляр компании), вы также удалите ее поставщиков? Если вы удалите «Starbucks» (кофейная компания в США), все ли поставщики кофейных зерен прекратят свое существование? Это все зависит от вашего домена и приложения, но я предлагаю, скорее всего, ни один из ваших Entities, не Aggregate Roots, или, возможно, лучший способ думать о них, это то, что они являются Совокупными корнями, у которых нет «листьев» (ничего для агрегатный). Другими словами, компания не контролирует доступ и не контролирует жизненный цикл поставщиков. У него просто отношения один-ко-многим с поставщиками (или, возможно, многие-ко-многим).

Это подводит нас к Repositories. A Repository предназначен для хранения и извлечения Aggregate Roots. У вас их два (технически они ничего не агрегируют, но это проще, чем сказать «репозитории хранят агрегатные корни или сущности, которые не являются листьями в агрегате»), поэтому вам нужно два Repositories. Один для компании и один для поставщиков.

Надеюсь, это поможет. Возможно, Эрик Эванс скрывается здесь и скажет мне, где я отклонился от его парадигмы.

1 голос
/ 01 октября 2009

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

Корневые сущности всегда более гибкие, чем объекты-значения, несмотря на дополнительную работу по реализации. Я обнаружил, что объекты-ценности в модели со временем становятся реже по мере развития модели, и объекты, которые остаются объектами-значениями, обычно были теми, которые вы могли бы логически ограничить таким образом с первого дня.

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

...