В общем, у меня возникает соблазн ответить Mu (в дзенском смысле), потому что сценарий неверен с точки зрения DDD. В DDD мы начинаем с бизнес-требований и экспертов предметной области, и на их основе мы получаем модель предметной области.
Хотя это спорный момент, база данных является почти случайным артефактом бизнес-требований (которые почти всегда утверждают, что сущности должны быть сохранены).
Тем не менее, я постараюсь сделать все возможное.
В большинстве случаев заказ является довольно важным бизнес-объектом, и, очевидно, нам нужно знать о строках заказа, включая продукты в каждой строке, поэтому может показаться, что нам нужна связь от строки заказа (Order_Detail) к продукту.
Однако, когда нам дают конкретный продукт, нам редко нужно знать, в какие заказы он был включен, так что это сразу предполагает одностороннюю связь. Мы можем переходить от строки заказа к продукту, но не от продукта к строке заказа.
Однако приведенный выше анализ может оказаться ложным на более глубоком уровне. Представьте себе следующий разговор между разработчиком и экспертом в предметной области:
Разработчик: Мы создали эту связь между заказами и продуктами, чтобы всегда знать все о продуктах в конкретном заказе.
Exp: Звучит неплохо, но как насчет поставщика?
Разработчик: Это тоже включено.
Exp: Что происходит, когда мы меняем поставщика продукта?
Разработчик: Это будет неявно отражено и в данных заказа...
Пояснение: Это не то, что нам нужно. Мы хотим, чтобы данные отражали заказ на момент его отправки.
В этом случае оказывается, что на самом деле есть ошибка в схеме базы данных. Проблема может быть вызвана отчетностью, потому что бизнес-аналитики могут захотеть запустить отчеты о том, как разные поставщики влияют на прибыль (что я знаю).
В таком случае можно предположить, что ассоциацию со строками заказов следует полностью свести к продукту. Заказы должны содержать исторические (моментальные) данные о продуктах, а не текущие данные о продуктах.
Мы можем даже ввести ProductSnapshot
Объект-значение, который семантически отражает Product
Сущность, чтобы смоделировать это в модели предметной области.
В целом кажется все более и более разумным моделировать Order
как совокупность самого себя и строк заказов (с ProductSnapShots
), но как насчет отношений между заказами и клиентами?
Насколько я понимаю ассоциации и агрегаты, ассоциации определяют агрегаты. Учитывая заказ, хотели бы мы знать о клиенте? Вероятно. Учитывая клиента, вы хотели бы знать о заказах? Наверное.
Это предполагает двустороннюю связь, которая делает Customer
агрегированным корнем. Это означает, что у вас будет CustomerRepository
, но не OrderRepository
. Каждый раз, когда вам нужен Орден, вы должны получить его через Customer
.
В некоторых случаях это может иметь смысл, в то время как в других ситуациях это может быть очень неуклюжим. Это действительно зависит от бизнес-требований...
Вы также можете рассмотреть возможность создания OrderRepository
, но это вторгается в совокупный корень Customer
. Если вы это сделаете, станет неясно, на ком лежит ответственность за Орден. Что произойдет, если вы перейдете от заказа к клиенту? Customer
есть список Приказов, но все ли они заполняются в памяти, если вы читаете Приказ из OrderRepository
?
Вероятно, нет, но они, вероятно, будут, если вы прочитаете Заказчика из CustomerRepository
. Дело в том, что анализ агрегированных корней важен, и как только вы определили агрегат, вам придется придерживаться его и уважать.
Из-за этого я предпочитаю маленькие агрегаты большим агрегатам, поэтому в этом примере я бы ограничил агрегат до Order
и его строк заказа и не имел связи между Order
и Customer
.
Отсутствие формальной связи между Order
и Customer
не означает, что мы вообще не можем связать их, но нам нужны явные услуги, чтобы получать все Заказы для данного Клиента. Мы не можем просто переходить от одного к другому.
person
Mark Seemann
schedule
05.03.2010