Що таке DDD: як працює, та як впровадити
- Катерина Мещерякова
- 7 вер. 2023 р.
- Читати 10 хв
Оновлено: 2 трав.

Ідея про те, що системи програмування мають базуватися на конкретній предметній області, здається очевидною, проте коли розробник Ерік Еванс зібрав докупи усі патерни, методи та нюанси подібного підходу, вийшла ґрунтовна фундаментальна праця на півтисячі сторінок. Він назвав нову розробницьку філософію Domain-Driven Design (DDD) або предметно-орієнтоване проєктування.
У цьому матеріалі ми з’ясовуємо, що таке DDD, чи актуальна методологія зараз, які основні концепції варто знати перед тим, як з нею працювати, які переваги та недоліки є у запропонованого Евансом підходу. Розібратися у предметно-орієнтованому проєктуванні нам допоміг Андрій Попов, Back-end Tech Lead в AMO, одній з компаній екосистеми Genesis. Андрій керує бекенд-командою у проєкті з розробки застосунку в галузі Health&Fitness. Загалом він має більш ніж десятирічний досвід в IT, працював в нішах Education та Betting, де зокрема застосовували концепції предметно-орієнтованого дизайну.

Що таке DDD, і чому він потрібен у сучасній розробці
Domain-Driven Design — це підхід до розробки, відповідно до якого створення систем програмного забезпечення базується на домені, тобто на предметній області, в якій працює компанія. Таких доменів може бути один або декілька — залежно від комплексності конкретного бізнесу. Прикладом бізнесу, де поєднано кілька доменів, може бути великий ecommerce-проєкт, залізниця, пошта, фінансова організація тощо.
У великих проєктах часто буває так, що розробники концентруються тільки на тій частині бізнес-логіки, з якою вони безпосередньо працюють. Через це виникає низка труднощів. Окремі члени команди не бачать повну картину того, що відбувається в коді, і, відповідно, не можуть врахувати специфіку системи, не бачать найбільш вдалі архітектурні рішення, й фокусуються на цікавих з точки зору розробки, але другорядних з точки зору бізнесу завданнях. DDD допомагає ці проблеми усунути.
Предметно-орієнтоване проєктування передбачає, що кожен у команді має цілісне уявлення про код, про домен та про бізнес-процеси. Цього досягають, зокрема, завдяки моделі предметної області, яку розробляють на початку, та єдиній мові, якою комунікують всі стейкхолдери. Тоді й розробники, і бізнес мають однакове бачення системи — і необхідність у постійній синхронізації та ґрумінгах зникає.
Важливо, що DDD — це не конкретна технологія чи методологія. Це набір правил та підходів, які полегшують процес розробки. У сучасному програмуванні все більше девелоперських команд відмовляється від монолітів на користь мікросервісів — і DDD стає їм у пригоді: допомагає визначити межі кожного мікросервісу, основні концепції, агрегати та пов’язану з ними бізнес-логіку. Завдяки цьому розробники мають змогу зробити більш структурний та масштабований код.
У предметно-орієнтованому проєктуванні є два рівні — тактичний та стратегічний. Розберемося з основними поняттями для кожного з них.
Основні принципи DDD
У основі терміну лежить поняття предметної області (domain) — це галузь, у якій працює організація. На початку в особливостях цієї галузі може бути важко орієнтуватися, однак з часом усі залучені до проєкту розбираються в усіх нюансах. Втім, створити всеохопну модель будь-якого складного бізнесу не вийде, тому в доменах виділяють subdomains — предметні підобласті, що ранжуються відповідно до їхньої фактичної функціональності. Субдомени дають змогу швидше визначити різні частини предметної області, необхідні для вирішення конкретного завдання.
Серед них виділяють змістове ядро (core domain) — найбільш важливий субдомен. По суті, це унікальна ціннісна пропозиція, яка вирізняє конкретний бізнес. Саме на ній мають фокусуватися найкращі розробники та саме у неї слід спрямовувати найбільше інвестицій — адже core domain напряму впливає на отримання прибутку та успіх бізнесу.
Натомість деякі інші аспекти бізнесу є важливими, але не ключовими. Тоді їх відносять до службової підобласті (supporting subdomain). Більшість таких юнітів мають спеціалізацію. Якщо ж її немає, а підобласть потрібна для всього бізнесу — вона називається неспеціалізованою (generic subdomain).

Одна з найважливіших концепцій доменно-орієнтованого проєктування — це ubiquitous language або усеохопна мова. Фактично, це набір термінів для конкретної команди, в створенні якого беруть участь усі дотичні до проєкту люди — програмісти, експерти предметної області, аналітики тощо. Структурним одиницям коду, таким як класи, методи, змінні чи назви, присвоюють конкретні назви, які базуються на моделі домену. Завдяки цьому код стає чітким та зрозумілим для всіх.
«Єдина термінологія, якою оперують бізнес і команда розробки, дозволяє усувати прогалини у взаєморозумінні. Наприклад, зараз ми в AMO ми робимо застосунок для тренувань. У нас не імплементовано DDD у чистому вигляді, однак є деякі технічні елементи концепції з тактичних патернів. Крім того, ми ввели Ubiquitous Language, наскільки це було можливо. Так, кожен має точно знати, що значить тренування, з чого воно складається тощо. У теорії створити та імплементувати таку мову просто, одна на практиці цей процес доволі складний. Потрібна людина, яка буде стежити за її застосуванням. Ідеально, якщо це людина, яка працює на перетині розробки та бізнесу, наприклад, дата- чи бізнес-аналітик», — каже Андрій Попов.
В межах предметної області сенс певного терміна або поняття може відрізнятися. Існує певна межа — і за нею поняття єдиної мови набувають конкретного контекстного значення. Така межа називається обмеженим контекстом (bounded context). Це ще одна критично важлива характеристика DDD, яка полягає в тому, що на різних рівнях проєкту можуть використовуватися декілька моделей зі своїми єдиними мовами. Завдяки bounded context зв’язки між моделями зменшуються — і це теж запобігає складному та заплутаному коду. Bounded Context дозволяє дублювати моделі в різних командах, щоб кожна могла вільно змінювати цю модель у себе, незалежно від іншої.
Тактичний рівень DDD
Аби реалізувати специфічний bounded context, на тактичному рівні використовують низку шаблонів. На відміну від стратегічного моделювання, яке фокусується на загальному управлінні бізнесом, такі шаблони використовують для ітеративної розробки.
Сутності (entity) використовують, коли потрібно змоделювати унікальні поняття, або ті, що відрізняються від інших об’єктів у домені. Їх можна визначити за певним ключовим атрибутом або комбінацією атрибутів, що не залежать від інших характеристик.
Якщо ж для об'єкта не важлива індивідуальність, і для його визначення достатньо власних атрибутів, його вважають об'єктом-значенням (value object). Їх легше створювати та підтримувати, тому розробники намагаються використовувати об’єкти-значення частіше, ніж сутності.
Значні зміни в стані домену відображають події (domain event). Вони використовуються для передачі змін і запуску дій між різними частинами системи.
Модулі (module) можуть бути організовані навколо конкретних концепцій домену та містять класи, функції чи компоненти, що відповідають за обробку логіки та даних, пов'язаних з конкретною концепцією предметної області.
Агрегат або сукупність (aggregate) — це кластер пов’язаних між собою сутностей та об’єктів значення, які розглядаються як єдине ціле. Вони забезпечують узгодженість та цілісність змін у своїх межах.
Фабрики (factory) існують, щоби відтворювати інші об’єкти, а сховища (repository) надають інтерфейс для доступу та керування агрегатами.

У яких випадках потрібен DDD
DDD призначене для створення моделей доменів зі складною бізнес-логікою. Це означає, що найкраще концепція підійде для вузьких специфічних ніш — наприклад, фінтех або e-commerce. «Канонічне предметно-орієнтоване проєктування містить дуже багато понять, патернів та підходів. Використовувати їх усі у стартапі або проєкті, запущеному з нуля, важко й не доцільно», — коментує Андрій Попов.
Коли команді варто обирати перехід на DDD? Наприклад, якщо це складна ніша з багатьма окремими сутностями. «Раніше я працював саме над таким проєктом. DDD імплементували з нуля, оскільки ніша передбачає багато складних для розуміння сутностей. Потрібно було пильно стежити за правильністю термінології, тому ми зробили окрему сторінку з глосарієм, де було пояснення багатьох специфічних для ніші понять. Була навіть відповідальна людина — бізнес-аналітик, який транслював вимоги конкретно під цю область, а програмісти намагалися писати код відповідно до бізнес-правил», — говорить Андрій Попов.
Як імплементувати DDD у себе в проєкті
Імплементувати методологію може бути складно. На цьому шляху є декілька челенджів. «Найперше — розробникам може бути банально нецікаво працювати з новою концепцією. Буває так, що термінологію прописує бізнес-команда — і технічним фахівцям потрібно до неї звикати. А означає, що треба повністю змінювати стиль роботи, і витрачати додаткові час та енергію на щось іще, окрім написання коду.
З іншого боку — перехід на нові правила може не цікавити сам бізнес, бо на це потрібно виділяти час, ресурс, призначати відповідальну особу, яка буде за всім стежити», — підкреслює Андрій Попов.
Однак, з часом DDD перестає уповільнювати роботу команди й тільки полегшує розробку. «Нещодавно ми запустили ще один проєкт в ніші Health and Fitness. Мене призначили лідом, дали невеличку команду. Я одразу вирішив, що ми будемо використовувати глосарій з термінологією, інакше буде плутанина і люди не розумітимуть, що і як влаштовано в коді. Поки що тільки цим словником важко обмежуватися, адже під час написання абстракцій чи алгоритмів все одно доводиться щось додумувати.
Втім, ми уже маємо певний каркас, завдяки якому розробники та бізнес краще одне одного розуміють. Це, знову таки, не канонічне предметно-орієнтоване проєктування — здебільшого ми послуговуємося суто технічними речами, такими як фабрики, репозиторії, сервіси, доменні моделі тощо. Однак подібний підхід все одно покращує чистоту коду, й сам процес розробки стає комфортнішим», — розповідає розробник.
Виклики при впровадженні Domain-Driven Design
Повноцінне впровадження DDD вимагає часу, сеньйорності команди та готовності до організаційних змін. Ось кілька труднощів, які можуть виникнути в цьому напрямі:
На початку потрібно витратити багато часу та ресурсів.
Щоб команда почала повноцінно працювати з DDD, потрібно витратити час, аби познайомити всіх із бізнес-доменом, на моделювання bounded context, формалізацію ubiquitous language, а ще — розробку ізольованої архітектури для кожного контексту. На це треба закладати час на етапах discovery та проєктування — що може суперечити прагненням завершити розробку якомога швидше. Особливо це стосується проєктів із завантаженим roadmap.
Потрібно добре продумати координацію між командами.
У системах із кількома bounded context виникає потреба в продуманій інтеграції — через контракти, API або подієву взаємодію. Без чітко визначених правил комунікації (наприклад, event contracts, versioned interfaces) буде хаос, що нівелюватиме переваги DDD. Тому, щоб цього уникнути, потрібно підстрахуватися: узгодити формати API, async communication, антикорупційних шарів (ACL) тощо.
Може виникнути потреба у перебудові процесів.
На відміну від класичного розподілення на фронтенд чи бекенд, DDD передбачає структуризацію команд навколо доменів. Крім того, через перехід на крос-функціональні доменні команди, якого часто вимагає DDD, доведеться змінювати процеси планування, пріоритезації та відповідальності. Роль продакт-менеджера також трансформується — він стає фасилітатором між бізнесом та інженерами. Усе це передбачає зрілість процесів, розвинений менеджмент стейкхолдерів і готовність змінити існуючу організаційну культуру.
Переваги DDD
покращує чистоту та структурованість коду;
розробники та бізнес говорять однією мовою — що дозволяє уникнути хаосу та плутанини;
архітектура точно відображає бізнес (предметну область) та враховує його специфічні особливості;
автономна робота над різними частинами системи забезпечує кращу масштабованість;
у великих проєктах з кількома технічно незалежними командами DDD чітко декларує способи їхньої взаємодії;
компоненти та бібліотеки, які створюють у межах DDD, можна використовувати у майбутніх проєктах — що заощаджує час розробників.
Недоліки DDD
на початку DDD суттєво уповільнює робочий процес;
розробникам чи бізнесу можуть не подобатися нові правила, що призведе до опору та конфліктів;
ускладнення коду (якщо до нього «притягнути» зайві пункти методології);
збільшення кодової бази через специфічні технічні рекомендації;
DDD вимагає залучення кваліфікованих експертів предметної області та досвідчених розробників, тому може бути ресурсомістким;
деякі інструменти та фреймворки можуть не вписуватися в принципи DDD, а це ускладнить реалізацію функціонала.
Сучасні технології, що підтримують DDD
Подієво-орієнтована архітектура
Один із ключових технологічних партнерів DDD — це Event-Driven Architecture (EDA). Вона дає змогу реалізувати асинхронну комунікацію між bounded context, зберігаючи слабке зв’язування між доменами. Замість прямого виклику методів один контекст публікує події, а інший на них реагує. Так залежності між сервісами стають меншими, а гнучкість системи — більшою.
Типові інструменти: Apache Kafka, RabbitMQ, AWS SNS/SQS.
Контейнеризація та мікросервіси
DDD чудово поєднується з мікросервісною архітектурою. Docker та Kubernetes дозволяють фізично відокремити контексти один від одного, забезпечити автономність, масштабованість і незалежні цикли релізу для кожного домену. Згодиться для складних продуктів, де різні команди відповідають за окремі частини системи.
Автоматизація та CI/CD
DDD створює сприятливі умови для розділення відповідальності, і це підсилюється через CI/CD-процеси. Кожна команда може мати власний пайплайн, налаштований під реліз функціоналу в конкретному домені. Це зменшує «гальма» через міжкомандні залежності та дозволяє масштабувати швидкість розробки без шкоди для стабільності.
Типові інструменти: GitHub Actions, GitLab CI/CD, ArgoCD, CircleCI.
Інструменти для моделювання домену
Робота з DDD починається з моделювання бізнес-логіки, і тут важливо мати візуальні та фасилітаційні інструменти. EventStorming дає змогу побудувати спільне розуміння процесів між бізнесом та технічними фахівцями. Context Mapping і Domain Storytelling допомагають виявити bounded context, зони відповідальності та ключові зв’язки між ними.
Популярні практики та підходи: EventStorming, Context Maps, Domain Storytelling, C4 Model.
Ось розділ «Зв’язок DDD з іншими підходами та концепціями», оформлений у тому ж стилі та з SEO-оптимізацією:
Як DDD взаємодіє з іншими підходами у розробці
DDD і мікросервіси
DDD часто стає базою для проєктування мікросервісної архітектури. Bounded context у DDD — це природна межа для мікросервісу: кожен контекст відповідає за власну частину бізнес-логіки, має свою модель і може розвиватися автономно. Підхід допомагає уникати «роздутих» сервісів, у яких змішується логіка різних доменів.
DDD і Agile
Обидва підходи фокусуються на розумінні цінності для бізнесу. Якщо Agile — це фреймворк для гнучкої доставки, то DDD — це фреймворк для глибокого розуміння того, що саме потрібно доставити. Вони чудово поєднуються: DDD допомагає формулювати якісні user stories, а Agile — швидко реалізовувати їх у межах ітерацій.
DDD і DevOps
Domen-Driven Design дає змогу структурувати процеси так, щоб DevOps-практики реалізовувалися більш ефективно. Команди, організовані навколо bounded context, можуть незалежно розгортати свої частини системи, будувати власні CI/CD пайплайни та моніторити свою зону відповідальності без зовнішніх блокерів.
DDD і TDD
DDD підсилює TDD (Test-Driven Development) тим, що дозволяє тестувати бізнес-логіку ізольовано в межах одного домену. Оскільки модель не «зашита» у всю систему, а локалізована в межах контексту, її простіше покривати юніт-тестами, розділяючи поведінку від інфраструктури.
DDD для кар’єри
Розробникам рівня сеньйор з амбіціями стати тимлідами точно корисно мати в резюме рядок про знання принципів DDD, говорить Андрій Попов. Не факт, що ці знання згодяться у роботі, оскільки не всі (навіть великі) проєкти застосовують DDD. Однак обізнаність у цьому підході покаже і рівень досвіду, і менеджерські амбіції.
«Будь-які додаткові знання стануть плюсом. А якщо людина прагне до керівної посади, їй варто розумітися не лише на технічних патернах, а й на стратегічних речах, зокрема, комунікації між командами та бізнесом. Втім, на початку кар’єри краще присвятити час заглибленню у технічні нюанси розробки обраною мовою», — уточнює Андрій.
Корисні матеріали
Весь теоретичний матеріал з DDD зібраний у трьох канонічних виданнях — синій, червоній та зеленій книзі.

Синьою книгою називають працю Еріка Еванса «Предметно-орієнтоване проєктування: структуризація складних програмних систем». Еванс — основоположник концепції DDD, тож у книзі він ґрунтовно пояснює, як включити ефективне доменне моделювання у розробку ПЗ. Автор не описує конкретні технології, пропонуючи натомість підходи, інструменти та методи, які полегшать розробку ПЗ у складних доменах.
«Цю книжку варто прочитати хоча б тому, що це першоджерело знань про DDD. Однак не розраховуйте, що буде легко: вона доволі специфічна, я зміг дочитати її лише з третього разу», — каже Андрій. «Новачки навряд чи зможуть одразу застосувати методології, про які пише Еванс. А от якщо ви розробник зі значним комерційним досвідом та працювали з великими замовниками у незнайомій для вас царині — то ця книга точно стане в пригоді».
Червона книга — це «Реалізація методів предметно-орієнтованого проєктування», яку написав Вон Вернон. На відміну від попереднього «підручника», де описуються фундаментальні принципи DDD, у виданні американського архітектора програмного забезпечення є більш практичні поради. Він із самого початку знайомить читачів з проблемами реальної розробки й показує, як їх вирішити за допомогою методів та шаблонів DDD.
Зелену книгу, «Предметно-орієнтоване проєктування: найголовніше», також написав Вон Вернон. З усіх трьох вона найпростіша для сприйняття. По суті, це короткий довідник з основними концепціями DDD та простими прикладами з досвіду Вернона, на яких видно переваги підходу.
Загалом, DDD — це, швидше, звід рекомендацій, ніж суворий набір правил. Тимліди технічних команд можуть обирати лише деякі рекомендації з цього підходу — і процес не поламається. Але навіть декілька інструментів предметно-орієнтованого проєктування дадуть змогу простіше допрацьовувати, змінювати та тестувати застосунок у майбутньому.