Я хотел бы сделать, некоторое осуществление и применять DDD к моей Модели предметной области относилось к базе данных Northwind. Даже если Northwind является примером, я предполагаю, что он был сделан для удовлетворения некоторых "виртуальных бизнес-" требований. Таким образом, цель состоит в том, чтобы иметь Модель предметной области, которая уважает DDD, и данные хранятся в базе данных Northiwnd.
Рассмотрите эту модель постоянства EF:
(источник: developpeur.org)
Заметьте, что у нас есть только объекты и два пути отношения. Я хотел бы иметь реальный DM, который уважает DDD. Больше, моя модель DM не должна быть зеркалом моей базы данных
Как Вы изменили бы des отношения, чтобы иметь только один путь отношения или два пути при необходимости.
Есть ли какой-либо many-one или one-many отношения, которые могли быть изменены на один одному?
Как был бы Вы модель агрегироваться?
Как насчет Объектов Значений, сервисов и фабрик в случае необходимости?
Я знаю, что, вероятно, я взгляд shoul на бизнес-требования и что взгляд, как модель должна измениться, но хотела бы иметь Ваш advaice на этом.
Попросите детали, если мой вопрос не ясен.
Заранее спасибо.
В общем, я склонен ответить 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, вам придется придерживаться его и уважать его.
Это заставляет меня отдавать предпочтение малым агрегатам перед большими, поэтому в данном примере я ограничу агрегат Заказом
и его строками заказов, и не буду связывать Заказ
и Клиент
.
Отсутствие формальной ассоциации между Заказ
и Клиент
не означает, что мы не можем связать их вообще, но нам нужны явные услуги, чтобы предоставить нам все заказы для данного клиента. Мы не можем просто переходить от одного к другому.