Постараюсь кратко описать мой теоретический и не очень актуальный, но интересующий вопрос.
В подходе DDD при проектировании приложения отталкиваются от проектирования доменной логики. Если есть у кого-то опыт, посоветуйте, как тогда проектировать базу данных. А то подход DDD мне теоретически понятен когда незыблемая БД уже есть. А если ее нет и ведется командная разработка и когда одну часть системы делает одна команда разработчиков, а другую - другая, то уже совсем не понятно. Если сначала проектировать БД для всей системы, то название domain-dd не совсем себя оправдывает, так как отталкиваемся уже не от проектирования домена, а от проектирования БД...
Постараюсь теперь подробнее описать вопрос, с приведением простого теоретического примера конкретной ситуации, в которой этот вопрос может возникнуть.
В DDD есть два термина:
Ubiquitous language - повсеместный язык
Bounded context - ограниченный контекст
То есть одна и та же сущность должна быть по-разному спроектирована в зависимости от того, в каком контексте она используется.
Например, если рассмотреть какую-нибудь систему ERP для планирования ресурсов предприятия, в котором сотрудники сидят и с помощью приборов делают работы. В этой системе могут быть следующие сущности:
Сотрудники
Приборы
Работы
У системы могут быть две функции:
Вести учет Приборов, то есть за каким сотрудником числится какой прибор.
Вести учет Работ, то есть какие работы были или будут сделаны и какие сотрудники и приборы в этом участвуют.
На сколько я понимаю, понятие ограниченного контекста (bounded context) введено, чтобы разграничить проектирование приложения на части, чтобы отдать эти части для разработки разным командам программистов. На сколько я понимаю, в данном примере ограниченные контексты это и есть две функции системы: учет пользователей и учет приборов.
Понятие повсеместного языка - на сколько я понимаю это когда заказчик и разработчик разговаривают на одном языке. В нашем примере заказчика два: тот отдел организации, который следит за инвентарем и тот отдел, который следит за выполнением работ.
Если взять отдел инвентаризации, то Прибор в данном контексте должен иметь одни поля, например, модель, инвентарный номер, и т.д. А в контексте учета работ, у Прибора должны быть другие поля, но некоторые совпадают: так же модель, но еще и технические характеристики, и установленная ОС, ну а инвентарный номер здесь не нужен. Так же и у Сотрудника разные поля в разных контекстах.
То есть, ситуация такая, что одной команде разработчиков дали разрабатывать контекст инвентаризации, а другой - учета работ. При этом для одной команды прибор и сотрудник - это одно, а для другой команды прибор и сотрудник это другое.
Вопрос. Как двум командам разработчиков, работающим над разными частями системы и видящих логические сущности приложения по-разному, приступить к проектированию базы данных? Ведь если они сначала скооперируются и сделают общую базу данных, где есть сотрудники со всеми полями и дополнительными таблицами и приборы со всеми полями и дополнительными таблицами, то это уже будет не совсем DDD, так как отталкиваемся не от проектирования домена, а от проектирования данных.
Так же интересуют любые советы и если кто поделится своим опытом, о том, как проектировать БД когда над системой работают несколько разных групп людей с разным видением...
Ответ
На сколько я понимаю, понятие ограниченного контекста (bounded context) введено, чтобы разграничить проектирование приложения на части,
чтобы отдать эти части для разработки разным командам программистов.
Мне кажется, что в первую очередь здесь имеет смысль разделение на модули, а возможность разработки различными командами это уже следствие такого разделения.
Так как у сущности может быть множество атрибутов которые, зачастую, используются небольшими группами в различных функциях проще сразу разделить такую сущность на эти группы атрибутов и использовать их независимо, чем везде
таскать одну и туже сущность большая часть которой, в заданном контексте, не нужна и образует только лишнюю связанность кода.
У Вас есть сервер приложений где описана модель Ваших данных и бизнес-логика которая умеет менять состояние этой модели.
Модели должно быть все равно где и как хранится ее состояние.
В Вашей ситуации главное то, как выглядит модель данных на сервере приложений и то, как реализована ее бизнес-логика.
Ведь описание сущностей и их атрибуты ровно как и методы этих сущносетй должны быть понятны всем участникам процесса и соответсвовать тому как они все себе это представляют
опираясь на общий язык.
На сколько я понимаю, DDD подразумевает длительный процесс выработки модели предметной области в течении которого она будет достаточно часто меняться пока более менее не устаканится.
В таком случае сразу скооперироваться и сделать общую базу данных так просто не получится, так как модель еще толком не ясна. Поэтому, в первую очередь, Вы будете создавать и менять
модель данных на сервере приложений и уже во вторую очередь придумывать как она будет хранится. Но это не означает то, что в процессе изменения модели данных так же сильно должно меняться и хранилище данных (может меняться только слой абстракции в виде представлений).
Что касается БД - то тут можно пойти по разному. У вас есть база данных которая хранит состояние Вашей модели и осуществляет проверку целостности данных.
На БД часто налагают различные технические требования так, что вопрос распределения данных по таблицам может, в большей степени,
относится к решению этих технических проблем, а не к соответствию 1 в 1 с Вашей моделью данных.
То, что у сотруника в разных контекстах есть как общие атрибуты так и частные
напоминает наследование. А для наследования придумали различные способы хранения данных в таблицах, такие как Single Table Inheritance, Class Table Inheritance и Concrete Table Inheritance
В Вашем случае вполне может быть подходящим второй способ. Тогда Вы сможете определить и выделить общие черты нужных сущностей и положить их в одну таблицу позволив разным командам создать таблицы для атрибутов этой сущности относящихся только к их задачам.
Или даже третий способ для начала, чтобы быть полностью независимыми друг от друга.
У каждого подхода будут как свои плюсы так и минусы как в плане добавления\удаления атрибутов так и в плане взаимопересечения команд и дублирования данных.
Независимо от варианта со структурой таблиц стоит использовать дополнительный слой абстракции над этими таблицами в виде представлений. Такой подход позволит склеить разные или разделить одну таблицы.
В дальнейшем, когда сама модель данных перестанет сильно меняться, можно будет рассмотреть первый вариант. Это должно будет упростить логику приложения и, возможно, снизить размер сохраненного состояния.
Ну и когда над одной БД работают различные группы людей особенно с разным видением я думаю, что стоит в первую очередь выработать какие-то общие правила (стандарты) как минимум в области именования обьектов.