2009-09-25 5 views
16

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

public class Foo{ 
    private readonly Bar Bar; 
} 

Я хочу, чтобы обеспечить функциональность для пользователей, чтобы выбрать Bars для Фооса из определенного списка (и его изменений).

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

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

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

+0

Нет такой вещи, как глупый вопрос, просто глупые ответы;) Кстати, этот вопрос мне очень помог – Eldar

ответ

16

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

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

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

+0

Это имеет смысл. Если у вас есть что сказать, продолжайте. :) –

+0

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

+1

Еще одно предположение, которое приходит мне на ум, заключается в том, что если ваш Бар является автономным (может быть представлен как отдельный список) и зависит (работает внутри Foo) одновременно, возможно, у вас на самом деле есть два объекта. Короткий пример: Group {Name, Price} - должен быть как внутри Order/Product, так и представлен отдельно, но если вы разделите его на Group {Name} и ProductGroup {Group, Price}, вы представляете Группу отдельно, сохраняя ProductGroup как часть совокупности. – queen3

2

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

+0

И почему компания не может быть извлечен через сервис и подключен к Foo? –

+0

Как объекты ценности должны быть созданы/обновлены без контекста объекта? Разве это не будет маскировать службу как репозиторий, который не должен иметь объект ценности? –

+0

Позвольте мне объяснить, как я это сделал; Мне нужен способ получить данные из постоянного слоя. Я мог бы использовать DTO для извлечения данных, но я скорее использую объект value, потому что тогда я могу использовать объект в домене без сопоставления от DTO к объекту value. Объект, который я использую, - это класс из совокупного корня, в вашем случае Bar. Если бы я должен был сделать это для сущности, я бы использовал DTO (полученную через службу), чтобы заполнить список (combobox и т. Д.), И когда я выбрал правильный бар, я попросил бы репозиторий получить мне полный объект из совокупного корня. Надеюсь, это имеет смысл. – Fossmo

8

Причина, имеющие Агрегатные корни является:

  1. Они обеспечивают контролируемые и направленный доступ к композитным лицам
  2. Они могут применять правила, чтобы гарантировать, что вся совокупность действует

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

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

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

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

Смежные вопросы