DDD — совокупный корень — пример заказа и строки заказа

Я пытаюсь запачкать руки изучением DDD (путем разработки примера сайта электронной коммерции с такими объектами, как Order, OrderLines, Product, Categories и т. д.). Из того, что я мог понять о концепции совокупного корня, я подумал, что класс Order должен быть совокупным корнем для OrderLine.

Пока все шло хорошо, однако я сбит с толку, когда он определяет поток создания заказов из пользовательского интерфейса. Когда я хочу добавить строку заказа в свой объект заказа, как мне получить/создать экземпляр объекта OrderLine:

  1. Должен ли я жестко закодировать новый оператор OrderLine() в моем классе пользовательского интерфейса/сервиса?
  2. Должен ли я определить метод с такими параметрами, как productID, quantity и т. д., в классе Order?

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


person Chandu    schedule 01.12.2010    source источник


Ответы (2)


Из того, что я мог понять о концепции Aggregate Root, я подумал, что класс Order должен быть совокупным корнем для OrderLine.

Да, OrderLine, скорее всего, должен находиться в корне OrderLine, поскольку OrderLine, скорее всего, не имеет смысла вне родительского Order.

Должен ли я жестко кодировать новый оператор OrderLine() в моем классе пользовательского интерфейса/сервиса?

Вероятно, нет, хотя это часто случается, и это работает. Проблема, на мой взгляд, заключается в том, что создание объекта часто происходит в разных контекстах, и ограничения проверки различаются в зависимости от этого контекста.

Должен ли я определить метод с такими параметрами, как productID, количество и т. д., в классе Order?

As in:

public OrderLine AddOrderLine(Product product, int Quantity ... )

Это один из способов сделать это. Обратите внимание, что я использовал класс Product вместо ProductId. Иногда одно предпочтительнее другого. Я обнаружил, что часто использую оба по разным причинам - иногда у меня есть идентификатор, и нет веской причины извлекать совокупный корень, иногда мне нужен другой корень для проверки операции.

Другой способ сделать это — реализовать пользовательскую коллекцию для детей.

Так что я:

order.OrderLines.Add(product, quantity);

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

order.AddOrderLine(), order.AddXXX(), order.AddYYY(), order.AddZZZ()

против

order.OrderLines.Add(), order.ZZZs.Add(), order.YYYs.Add()

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

Это будет пример из учебника для паттерна Factory. Я добавляю такую ​​фабрику в свои пользовательские коллекции, чтобы поддерживать создание экземпляров в этих Add() методах.

person quentin-starin    schedule 01.12.2010
comment
Я не думаю, что order.OrderLines.Add больше OO. Существует объектно-ориентированная вещь, называемая инкапсуляцией. Если в вашем классе много XXX, ZZZ, YYY, лучше его перепроектировать (хороший объектно-ориентированный дизайн имеет тенденцию иметь много мелких объектов). Вы можете погуглить о преимуществах инкапсуляции коллекций и избежания крушений поездов (свободные интерфейсы — другой случай). - person Sergey Berezovskiy; 29.11.2011

Вы можете использовать фабрику OrderLine для получения экземпляров OrderLines. Вы бы "обновили" объект OrderLine на фабрике с параметрами, переданными в фабричный метод, а затем вернули бы новый экземпляр вашему объекту Order. Всегда старайтесь изолировать экземпляры и не делайте этого в пользовательском интерфейсе. Здесь есть вопрос , в котором используется этот метод.

Вот отличная книга, которая будет вам полезна в DDD.

person Matt    schedule 01.12.2010