Domain-Driven Design у React
Що таке Domain-Driven Design (DDD)
Domain-Driven Design - це підхід до проєктування ПЗ, за якого структура і логіка застосунку будуються навколо предметної області (domain), а не навколо технологій, фреймворків чи UI-деталей.
Простими словами:
"DDD - це коли код відображає реальний бізнес, а не технічну реалізацію."
Основна ідея
DDD каже:
Розділи систему на області предметного сенсу (домени) - наприклад: користувачі, замовлення, товари, платежі - і всередині кожної області будуй код, що відображає її бізнес-логіку.
Приклад у контексті React
Уяви інтернет-магазин:
Без DDD (за типами файлів)
components/
hooks/
pages/
utils/Все перемішано: UI, бізнес-логіка, дані. Щоб зрозуміти, як працює кошик, потрібно шукати код по всьому проєкту.
З DDD (за доменами)
src/
domains/
user/
model/
api/
ui/
product/
model/
api/
ui/
cart/
model/
api/
ui/Тепер все, що пов'язано з cart (кошиком), знаходиться всередині однієї предметної області. Вона інкапсульована і незалежна від інших.
Ключові принципи DDD, застосовні у фронтенді
| Принцип | Опис | Приклад |
|---|---|---|
| Bounded Context | Кожна доменна область (cart, user, product) - ізольована частина системи | domains/cart і domains/user не знають одна про одну напряму |
| Ubiquitous Language | Використовуй єдину мову (терміни домену) і в коді, і в бізнес-логіці | Не addItemToList, а addProductToCart |
| Encapsulation | Домен приховує свою внутрішню логіку, назовні віддає лише публічний API | domains/cart/index.ts експортує addToCart() |
| Separation of Concerns | UI, стан і бізнес-модель розділені, але всередині домену | ui/, model/, api/ всередині cart |
| Composability | Домени можуть об'єднуватися, але лише через чіткі межі | cart може використовувати product лише через спільний контракт |
DDD і React
У React-застосунках DDD найчастіше проявляється через:
- Feature-Sliced Design - реалізація шарів
entities,features,pagesза доменами; - Colocation - зберігання логіки, UI і моделей домену поруч;
- Hooks і моделі стану (
useUserModel,useCartStore); - Типізовані API-моделі (
domain/cart/model/types.ts); - Публічні інтерфейси (index.ts) - щоб кожен домен був ізольований.
Приклад структури DDD + React
src/
shared/
ui/
Button.tsx
domains/
user/
model/
store.ts
selectors.ts
types.ts
api/
getUser.ts
ui/
UserAvatar.tsx
UserProfile.tsx
index.ts
cart/
model/
store.ts
selectors.ts
api/
addToCart.ts
removeFromCart.ts
ui/
CartButton.tsx
CartList.tsx
index.ts
app/
providers/
router/
index.tsxЯк це поєднується з іншими принципами
| Підхід | Що дає | Як поєднується |
|---|---|---|
| Atomic Design | Впорядкований UI | Можна використовувати всередині shared/ui |
| Colocation | Код поруч з використанням | Кожен домен зберігає свої файли локально |
| Feature-Sliced Design | Шари і правила залежностей | DDD визначає що, FSD - як |
| React Hooks | Інкапсуляція логіки | Кожен домен має свої хуки useCart(), useUser() |
Переваги DDD у фронтенді
| Перевага | Опис |
|---|---|
| Чітка структура | Кожна частина коду належить конкретній предметній області |
| Ізоляція | Можна розвивати або рефакторити окремий домен незалежно |
| Спільна мова з бізнесом | Розробник і менеджер говорять одними термінами |
| Масштабованість | Нові домени додаються без хаосу |
| Контроль залежностей | Домени не "знають" деталі один одного |
Підсумок
| Що | Опис |
|---|---|
| Ідея | Архітектура будується навколо предметних областей (user, cart, product) |
| Основна одиниця | Domain - модуль, що відображає бізнес-логіку |
| Шари всередині домену | model, api, ui, lib |
| Принципи | Bounded Context, Encapsulation, Ubiquitous Language |
| Ціль | Відповідність структури коду бізнес-моделі і легка масштабованість |
У React DDD = коли твій код відображає реальний бізнес, а не просто UI.
Замість "у нас є компонент Form і компонент List" -> ти думаєш "у нас є домен User і домен Cart".
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.