DDD ( ДДД ):совокупный корневой вопрос
-
16-09-2019 - |
Вопрос
Допустим, у меня есть 2 объекта - Foo и Bar.Foo является совокупным корнем и содержит Bar.Насколько я понимаю, это должно выглядеть примерно так:
public class Foo{
private readonly Bar Bar;
}
Я хочу предоставить пользователям возможность выбирать столбцы для Foo из определенного списка (и изменять его).
Если предполагается, что репозитории предназначены только для агрегированных корней, это означает, что репозитория для объекта Bar не будет.
Это приводит к проблеме - панель не может быть создана / обновлена независимо без ссылки на Foo.
Означает ли это, что у Bar должно быть хранилище, несмотря на то, что оно не имеет смысла без Foo?
Решение
Если вы хотите выбрать из списка столбцы, где они не связаны с Foo, то это не совокупный корень.Например, вы не можете получить список элементов заказа без их порядка, поэтому это единый совокупный корень (Order), но вы можете получить список продуктов для назначения элементам заказа, поэтому Product не является частью совокупного корня заказа.
Обратите внимание, что, хотя OrderItem является частью корневого каталога Order aggregate, вы все равно можете создавать и обновлять его независимо.Но вы не можете получить его без ссылки на Заказ.То же самое для вашего Bar , даже если он был частью Foo, вы могли бы получить каждый (Foo.Bars) и работать с ним или выполнить Foo.AddBar(новая панель()).Но если вам нужно получить список без Foo, Bar не является частью Foo aggregate.Это отдельная сущность.
Ну, вот как я вижу DDD здесь, но я, конечно, не Эрик Эванс.
Другие советы
Причинами наличия агрегированных корней являются:
- Они обеспечивают контролируемый и направленный доступ к составным объектам
- Они могут применять правила, чтобы гарантировать, что вся совокупность является действительной
Мой дубль:
Если вам нужно выбрать Bar
объекты без Foo
, использовать BarRepository
.
Но...
Что, если вы обновите Bar
, и это нарушает правило проверки для его родительского Foo
?Если это может произойти, вы должны получить доступ Bar
через своего родителя Foo
.
Если, однако, вам нужно получить доступ к куче Bar
объекты (например, для пакетного задания или отчета), и вы знать это Foos
не будут сломаны, продолжайте и получите к ним доступ через BarRepository
.
Помните, что совокупные корни могут состоять из других совокупных корней.Вы можете обнаружить, что Bar
является самим совокупным корнем, дающим вам обоснование для BarRepository
:)
Вы уверены, что Bar должен быть единым целым?Есть ли у вас необходимость отслеживать его и изменять в домене?Если вы можете рассматривать его как объект value, я бы посоветовал вам извлечь его из сервиса, а затем "подключить" выбранный объект value к объекту Foo.Мгновения через выпадающий список.