Страницы

Поиск по вопросам

воскресенье, 12 января 2020 г.

Проектирование базы данных при DDD (Domain-Driven Design)

#база_данных #архитектура #проектирование #ddd


Постараюсь кратко описать мой теоретический и не очень актуальный, но интересующий
вопрос. 

В подходе DDD при проектировании приложения отталкиваются от проектирования доменной
логики. Если есть у кого-то опыт, посоветуйте, как тогда проектировать базу данных.
А то подход DDD мне теоретически понятен когда незыблемая БД уже есть. А если ее нет
и ведется командная разработка и когда одну часть системы делает одна команда разработчиков,
а другую - другая, то уже совсем не понятно. Если сначала проектировать БД для всей
системы, то название domain-dd не совсем себя оправдывает, так как отталкиваемся уже
не от проектирования домена, а от проектирования БД...



Постараюсь теперь подробнее описать вопрос, с приведением простого теоретического
примера конкретной ситуации, в которой этот вопрос может возникнуть.

В DDD есть два термина:


Ubiquitous language - повсеместный язык
Bounded context - ограниченный контекст


То есть одна и та же сущность должна быть по-разному спроектирована в зависимости
от того, в каком контексте она используется.

Например, если рассмотреть какую-нибудь систему ERP для планирования ресурсов предприятия,
в котором сотрудники сидят и с помощью приборов делают работы. В этой системе могут
быть следующие сущности: 


Сотрудники 
Приборы 
Работы 


У системы могут быть две функции: 


Вести учет Приборов, то есть за каким сотрудником числится какой прибор.
Вести учет Работ, то есть какие работы были или будут сделаны и какие сотрудники
и приборы в этом участвуют.


На сколько я понимаю, понятие ограниченного контекста (bounded context) введено,
чтобы разграничить проектирование приложения на части, чтобы отдать эти части для разработки
разным командам программистов. На сколько я понимаю, в данном примере ограниченные
контексты это и есть две функции системы: учет пользователей и учет приборов.

Понятие повсеместного языка - на сколько я понимаю это когда заказчик и разработчик
разговаривают на одном языке. В нашем примере заказчика два: тот отдел организации,
который следит за инвентарем и тот отдел, который следит за выполнением работ.

Если взять отдел инвентаризации, то Прибор в данном контексте должен иметь одни поля,
например, модель, инвентарный номер, и т.д. А в контексте учета работ, у Прибора должны
быть другие поля, но некоторые совпадают: так же модель, но еще и технические характеристики,
и установленная ОС, ну а инвентарный номер здесь не нужен. Так же и у Сотрудника разные
поля в разных контекстах.

То есть, ситуация такая, что одной команде разработчиков дали разрабатывать контекст
инвентаризации, а другой - учета работ. При этом для одной команды прибор и сотрудник
- это одно, а для другой команды прибор и сотрудник это другое.

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

Так же интересуют любые советы и если кто поделится своим опытом, о том, как проектировать
БД когда над системой работают несколько разных групп людей с разным видением... 
    


Ответы

Ответ 1



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

Комментариев нет:

Отправить комментарий