Ідея про те, що системи програмування мають базуватися на конкретній предметній області, здається очевидною, проте коли розробник Ерік Еванс зібрав докупи усі патерни, методи та нюанси подібного підходу, вийшла ґрунтовна фундаментальна праця на півтисячі сторінок. Він назвав нову розробницьку філософію 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. Мене призначили лідом, дали невеличку команду. Я одразу вирішив, що ми будемо використовувати глосарій з термінологією, інакше буде плутанина і люди не розумітимуть, що і як влаштовано в коді. Поки що тільки цим словником важко обмежуватися, адже під час написання абстракцій чи алгоритмів все одно доводиться щось додумувати.
Втім, ми уже маємо певний каркас, завдяки якому розробники та бізнес краще одне одного розуміють. Це, знову таки, не канонічне предметно-орієнтоване проєктування — здебільшого ми послуговуємося суто технічними речами, такими як фабрики, репозиторії, сервіси, доменні моделі тощо. Однак подібний підхід все одно покращує чистоту коду, й сам процес розробки стає комфортнішим», — розповідає розробник.
Переваги DDD
покращує чистоту та структурованість коду;
розробники та бізнес говорять однією мовою — що дозволяє уникнути хаосу та плутанини;
архітектура точно відображає бізнес (предметну область) та враховує його специфічні особливості;
автономна робота над різними частинами системи забезпечує кращу масштабованість;
у великих проєктах з кількома технічно незалежними командами DDD чітко декларує способи їхньої взаємодії;
компоненти та бібліотеки, які створюють у межах DDD, можна використовувати у майбутніх проєктах — що заощаджує час розробників.
Недоліки DDD
на початку DDD суттєво уповільнює робочий процес;
розробникам чи бізнесу можуть не подобатися нові правила, що призведе до опору та конфліктів;
ускладнення коду (якщо до нього «притягнути» зайві пункти методології);
збільшення кодової бази через специфічні технічні рекомендації;
DDD вимагає залучення кваліфікованих експертів предметної області та досвідчених розробників, тому може бути ресурсомістким;
деякі інструменти та фреймворки можуть не вписуватися в принципи DDD, а це ускладнить реалізацію функціонала.
DDD для кар’єри
Розробникам рівня сеньйор з амбіціями стати тимлідами точно корисно мати в резюме рядок про знання принципів DDD, говорить Андрій Попов. Не факт, що ці знання згодяться у роботі, оскільки не всі (навіть великі) проєкти застосовують DDD. Однак обізнаність у цьому підході покаже і рівень досвіду, і менеджерські амбіції.
«Будь-які додаткові знання стануть плюсом. А якщо людина прагне до керівної посади, їй варто розумітися не лише на технічних патернах, а й на стратегічних речах, зокрема, комунікації між командами та бізнесом. Втім, на початку кар’єри краще присвятити час заглибленню у технічні нюанси розробки обраною мовою», — уточнює Андрій.
Корисні матеріали
Весь теоретичний матеріал з DDD зібраний у трьох канонічних виданнях — синій, червоній та зеленій книзі.
Синьою книгою називають працю Еріка Еванса «Предметно-орієнтоване проєктування: структуризація складних програмних систем». Еванс — основоположник концепції DDD, тож у книзі він ґрунтовно пояснює, як включити ефективне доменне моделювання у розробку ПЗ. Автор не описує конкретні технології, пропонуючи натомість підходи, інструменти та методи, які полегшать розробку ПЗ у складних доменах.
«Цю книжку варто прочитати хоча б тому, що це першоджерело знань про DDD. Однак не розраховуйте, що буде легко: вона доволі специфічна, я зміг дочитати її лише з третього разу», — каже Андрій. «Новачки навряд чи зможуть одразу застосувати методології, про які пише Еванс. А от якщо ви розробник зі значним комерційним досвідом та працювали з великими замовниками у незнайомій для вас царині — то ця книга точно стане в пригоді».
Червона книга — це «Реалізація методів предметно-орієнтованого проєктування», яку написав Вон Вернон. На відміну від попереднього «підручника», де описуються фундаментальні принципи DDD, у виданні американського архітектора програмного забезпечення є більш практичні поради. Він із самого початку знайомить читачів з проблемами реальної розробки й показує, як їх вирішити за допомогою методів та шаблонів DDD.
Зелену книгу, «Предметно-орієнтоване проєктування: найголовніше», також написав Вон Вернон. З усіх трьох вона найпростіша для сприйняття. По суті, це короткий довідник з основними концепціями DDD та простими прикладами з досвіду Вернона, на яких видно переваги підходу.
Загалом, DDD — це, швидше, звід рекомендацій, ніж суворий набір правил. Тимліди технічних команд можуть обирати лише деякі рекомендації з цього підходу — і процес не поламається. Але навіть декілька інструментів предметно-орієнтованого проєктування дадуть змогу простіше допрацьовувати, змінювати та тестувати застосунок у майбутньому.