Skip to main content

Domain-Driven Design у React

Що таке Domain-Driven Design (DDD)

Domain-Driven Design - це підхід до проєктування ПЗ, за якого структура і логіка застосунку будуються навколо предметної області (domain), а не навколо технологій, фреймворків чи UI-деталей.


Простими словами:

"DDD - це коли код відображає реальний бізнес, а не технічну реалізацію."


Основна ідея

DDD каже:

Розділи систему на області предметного сенсу (домени) - наприклад: користувачі, замовлення, товари, платежі - і всередині кожної області будуй код, що відображає її бізнес-логіку.


Приклад у контексті React

Уяви інтернет-магазин:

Без DDD (за типами файлів)

javascript
components/ hooks/ pages/ utils/

Все перемішано: UI, бізнес-логіка, дані. Щоб зрозуміти, як працює кошик, потрібно шукати код по всьому проєкту.


З DDD (за доменами)

javascript
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Домен приховує свою внутрішню логіку, назовні віддає лише публічний APIdomains/cart/index.ts експортує addToCart()
Separation of ConcernsUI, стан і бізнес-модель розділені, але всередині домену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

javascript
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".

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.