Подтвердить что ты не робот

DDD: совокупный корневой вопрос

Скажем, у меня есть 2 объекта - Foo и Bar. Foo - это совокупный корень и содержит Bar. Насколько я понимаю, это должно выглядеть так:

public class Foo{
    private readonly Bar Bar;
}

Я хочу предоставить пользователям возможность выбирать Bars for Foos из определенного списка (и изменять его).

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

Это приводит к проблеме. Бар не может быть создан/обновлен независимо без ссылки на Foo.

Означает ли это, что в баре предполагается наличие репозитория, несмотря на то, что он не имеет смысла без Foo?

4b9b3361

Ответ 1

Если вы хотите выбрать из списка баров, где они не связаны с Foo, то это не является совокупным корнем. Например, вы не можете получить список OrderItems без их ордера, так что это единый корень агрегата (Заказ), но вы можете получить список продуктов для присвоения OrderItems, поэтому Продукт не является частью корневого агрегата заказа.

Обратите внимание, что хотя OrderItem является частью корневого агрегата Order, вы все равно можете его создать и обновить самостоятельно. Но вы не можете получить его без указания порядка. То же самое для вашего бара, даже если это было частью Foo, вы можете получить каждый (Foo.Bars) и работать с ним, или сделать Foo.AddBar(new Bar()). Но если вам нужно получить List без Foo, Bar не является частью совокупности Foo. Это отдельный объект.

Хорошо, что я вижу DDD здесь, но я не Эрик Эванс, конечно.

Ответ 2

Причинами наличия корней Aggregate являются:

  • Они обеспечивают контролируемый и направленный доступ к составным объектам.
  • Они могут применять правила для обеспечения достоверности всей совокупности.

Мой прием: Если вам нужно выбрать Bar объекты без Foo, используйте BarRepository.

Но... Что делать, если вы обновляете Bar, и он нарушает правило проверки для него parent Foo? Если это может произойти, вы должны получить доступ к Bar через него parent Foo.

Если, однако, вам нужно получить доступ к кучке объектов Bar (например, для пакетного задания или отчета), и вы знаете, что Foos не будет разбит, продолжите доступ к ним через BarRepository.

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

Ответ 3

Вы уверены, что Bar должен быть сущностью? У вас есть необходимость отслеживать его и изменять его в домене? Если вы можете рассматривать его как объект значения, я бы предложил вам извлечь его из службы и затем "подключить" выбранный объект значения к объекту Foo. Для мгновений через раскрывающийся список.