Как агрегировать репозитории?


Я работаю над крупномасштабной системой для телекоммуникационной компании. Я новичок в DDD и с трудом связываю разные части вместе. Наша нынешняя система построена с использованием NHibernate. В настоящее время он имеет более 600 таблиц, и весь доступ к данным осуществляется с помощью NHibernate, но для новой системы мы будем использовать EF. Ниже приведены несколько функциональных областей и примеры таблиц базы данных в каждой функциональной области.

Клиенты
----- >CustomerDemographics
----- >CustomerPayments
----- >CustomerTransactions

RoutingEngine
----- >InboundRoutes
----- >OutboundRoutes

ProvisioningEngine
----- >InboundSwithces
----- >OutboundSwitches
-----> RouterConfigs
----- >GatewayConfigs

BillingEngine
----- >InboundTraffic
----- >OutboundTraffic

Поскольку система должна быть модульно-тестируемой, я начал абстрагировать фактические сущности с шаблоном репозитория. Один подход заключается в создании одного объекта репозитория для каждой таблицы базы данных. Конечно, все эти классы репозиториев могут быть получены из универсального интерфейса репозитория. Однако это добавит довольно много накладных расходов с точки зрения обслуживания кодовой базы. В DDD я читал об этой концепции агрегатов, но я не уверен, как ее следует применять специально в контексте EF. Должны ли агрегатные объекты быть контейнерами этих хранилищ или они являются скорее контейнерами связанных контекстов (имея в виду что-то вроде ограниченных DbContexts)?

2 3

2 ответа:

Один из подходов заключается в создании одного объекта репозитория для каждой базы данных стол.

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

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

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

Должны ли агрегатные объекты быть контейнерами этих хранилищ или являются ли они скорее контейнером связанных контекстов (что-то означающих по линиям ограниченных DbContexts)?

Похоже, что то, что вы называете "функциональными областями", называетсяограниченными контекстами (BC) в DDD. (Не DbContext в EF). Кроме того, агрегаты не являются контейнеры репозиториев, они содержат группу связанных сущностей из вашей доменной модели. Стереотипным примером является модель заказа на продажу, в которой имеется агрегат заказа, состоящий из корня агрегата заказа и различных сущностей и объектов стоимости, таких как элементы строки заказа. Как указывалось выше, агрегаты - это доменные объекты, к которым репозитории должны предоставлять доступ. Таким образом, вы должны структурировать свои репозитории вокруг агрегатов, но, конечно, сначала вы должны определить свои агрегаты и БКС. Взгляните наэффективный агрегатный дизайн вон Вернона .

Кроме того, наличие 600 столов в одном БК кажется слишком большим и является потенциальным признаком того, что у вас есть несколько БК в игре. То, чего достигают BCs, - этофункциональная когезия , которая, в свою очередь, является наиболее подходящим способом сгруппировать ("агрегировать" конфликты с термином DDD) ваши репозитории.

Агрегаты в ДДД границы последовательности - острова согласованности транзакций. Если у вас есть кластер объектов в модели предметной области, который должен быть транзакционно согласован и может рассматриваться как значимое концептуальное целое, то у вас, вероятно, есть агрегат. Между агрегатами вы можете иметь конечную согласованность.

Если вы занимаетесь новой разработкой, я бы рекомендовал сначала смоделировать домен в объектах, а затем решить, какой должна быть схема базы данных в качестве позже пройдет.

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