Применение DDD к базе данных Northwind

Я хотел бы сделать, некоторое осуществление и применять DDD к моей Модели предметной области относилось к базе данных Northwind. Даже если Northwind является примером, я предполагаю, что он был сделан для удовлетворения некоторых "виртуальных бизнес-" требований. Таким образом, цель состоит в том, чтобы иметь Модель предметной области, которая уважает DDD, и данные хранятся в базе данных Northiwnd.

Рассмотрите эту модель постоянства EF:

alt text
(источник: developpeur.org)

Заметьте, что у нас есть только объекты и два пути отношения. Я хотел бы иметь реальный DM, который уважает DDD. Больше, моя модель DM не должна быть зеркалом моей базы данных

  1. Как Вы изменили бы des отношения, чтобы иметь только один путь отношения или два пути при необходимости.

  2. Есть ли какой-либо many-one или one-many отношения, которые могли быть изменены на один одному?

  3. Как был бы Вы модель агрегироваться?

  4. Как насчет Объектов Значений, сервисов и фабрик в случае необходимости?

Я знаю, что, вероятно, я взгляд shoul на бизнес-требования и что взгляд, как модель должна измениться, но хотела бы иметь Ваш advaice на этом.

Попросите детали, если мой вопрос не ясен.

Заранее спасибо.

8
задан Glorfindel 25 June 2019 в 07:12
поделиться

1 ответ

В общем, я склонен ответить Mu (в смысле дзен), потому что сценарий неверен с точки зрения DDD. В DDD мы начинаем с бизнес-требований и экспертов домена и на их основе создаем модель домена.

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

Учитывая это, я постараюсь сделать все возможное.

В большинстве случаев заказ является довольно важным бизнес-объектом, и, очевидно, нам нужно знать о строках заказа, включая продукты в каждой строке, поэтому кажется, что нам нужна ассоциация от строки заказа (Order_Detail) к продукту.

Однако, когда нам предоставляется конкретный продукт, нам редко нужно знать, в какие заказы он был включен, так что это говорит об односторонней связи. Мы можем переходить от строки заказа к продукту, но не от продукта к строке заказа.

Однако вышеприведенный анализ может оказаться ложным на более глубоком уровне. Представьте себе следующий разговор между разработчиком и экспертом по домену:

Dev: Мы создали эту ассоциацию от заказов к продуктам, чтобы всегда знать все о продуктах в определенном порядке.

Exp: Это звучит хорошо, но что насчет поставщика?

Dev: Он тоже включен.

Exp: Так что произойдет, если мы изменим поставщика продукта?

Dev: Это будет неявно отражено и в данных заказа...

Exp: Это не то, чего мы хотим. Мы хотим, чтобы данные отражали заказ на момент отправки.

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

В таком случае можно предложить вообще оборвать связь между строками заказа и продуктом. Заказы должны хранить исторические (моментальные) данные о продукте, а не текущие данные о продукте.

Мы можем даже создать ProductSnapshot Value Object, который семантически отражает Product Entity для моделирования этого в Domain Model.

В целом, кажется все более разумным моделировать Заказ как агрегат самого себя и строк заказа (с ProductSnapShots), но как насчет отношений между заказами и клиентами?

Как я сейчас понимаю ассоциации и агрегаты, ассоциации определяют агрегаты. Учитывая заказ, хотели бы мы знать о заказчике? Скорее всего. Учитывая заказчика, хотели бы мы знать о заказах? Вероятно.

Это предполагает двустороннюю связь, что делает Заказчик корнем Агрегата. Это означает, что у вас будет CustomerRepository, но не будет OrderRepository. Каждый раз, когда вам нужен заказ, вы должны получить его через Customer.

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

Вы можете рассмотреть возможность создания OrderRepository, но это вторгнется в Customer Aggregate Root. Если вы сделаете это, то станет неясно, где лежит ответственность за заказ. Что произойдет, если вы перейдете от Заказа к Клиенту? Customer имеет список Заказов, но все ли они заполнены в памяти, если вы читаете Заказ из OrderRepository?

Скорее всего, нет, но они, вероятно, будут, если вы читаете Заказчика из CustomerRepository. Дело в том, что анализ Aggregate Roots важен, и как только вы определили Aggregate, вам придется придерживаться его и уважать его.

Это заставляет меня отдавать предпочтение малым агрегатам перед большими, поэтому в данном примере я ограничу агрегат Заказом и его строками заказов, и не буду связывать Заказ и Клиент.

Отсутствие формальной ассоциации между Заказ и Клиент не означает, что мы не можем связать их вообще, но нам нужны явные услуги, чтобы предоставить нам все заказы для данного клиента. Мы не можем просто переходить от одного к другому.

13
ответ дан 5 December 2019 в 12:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: