Применение DDD к базе данных Northwind - PullRequest
6 голосов
/ 04 марта 2010

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

Рассмотрим эту модель стойкости EF:

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

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

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

  2. Существуют ли отношения «один ко многим» или «один ко многим», которые можно изменить на один к одному?

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

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

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

Не стесняйтесь спрашивать подробности, если мой вопрос не ясен.

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

1 Ответ

12 голосов
/ 05 марта 2010

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

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

Тем не менее, я постараюсь сделать все возможное.

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

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

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

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

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

Exp: Так что же происходит, когда мы меняем поставщика для продукта?

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

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

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

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

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

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

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

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

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

Вы могли бы также подумать о создании OrderRepository, но это вторгается в Customer Совокупный корень. Если вы это сделаете, становится неясным, где лежит ответственность за Орден. Что произойдет, если вы перейдете от заказа к заказчику? У Customer есть список Орденов, но заполняются ли они все в памяти, если вы читаете Орден из OrderRepository?

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

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

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

...