Тек
February 11

🏗 DDD — от теории к практике: что это и как его внедрять  

Если ты когда-нибудь страдал от монолитного кода, который невозможно масштабировать, то пора познакомиться с Domain-Driven Design (DDD).

💡 DDD — это про логику бизнеса, а не про базы данных и API. Его цель — построить код вокруг реальных процессов компании, а не вокруг технических решений.

Но вот в чём проблема:

❌ DDD сложно внедрять

❌ Это не просто «новая архитектура» — это другой взгляд на код

❌ Без дисциплины DDD превращается в обычный антипаттерн

📌 Основные принципы DDD

✅ Bounded Context (Ограниченные контексты) — разделяем систему на независимые домены. Например, "Заказы" и "Биллинг" — это разные процессы, их не нужно смешивать.

✅ Ubiquitous Language (Единый язык) — разработчики, аналитики и бизнес должны говорить на одном языке. Если бизнес использует термин "Клиент", а в коде он называется "UserEntity", то кто-то тут явно врёт.

✅ Entities и Value Objects — сущности со своим жизненным циклом и неизменяемые объекты с бизнес-логикой.

✅ Domain Events — важные события, на которые реагируют другие части системы (например, "Заказ создан" → "Биллингу нужно выставить счёт").

📂 Как хранить код по DDD?

Одна из главных ошибок — думать, что DDD = микросервисы. Это не так. Можно строить DDD внутри одного сервиса, если правильно разложить код.

🔹 Базовая структура DDD-сервиса

/src
 ├── /order                # Контекст "Заказы"
 │   ├── /application      # Сценарии использования (Use Cases)
 │   │   ├── PlaceOrderHandler.py
 │   │   ├── CancelOrderHandler.py
 │   ├── /domain           # Бизнес-логика
 │   │   ├── /models       # Entities и Value Objects
 │   │   │   ├── Order.py
 │   │   │   ├── OrderItem.py
 │   │   │   ├── OrderStatus.py
 │   │   ├── /services     # Бизнес-сервисы (доменные)
 │   │   │   ├── OrderService.py
 │   │   │   ├── DiscountCalculator.py
 │   │   ├── /events       # Доменные события
 │   │   │   ├── OrderPlaced.py
 │   │   │   ├── OrderCancelled.py
 │   │   ├── /repositories # Абстракция работы с БД
 │   │   │   ├── OrderRepository.py
 │   ├── /infrastructure   # Взаимодействие с внешним миром
 │   │   ├── /persistence  # Реализация репозиториев
 │   │   │   ├── OrderSQLRepository.py
 │   │   ├── /messaging    # Интеграция с брокерами событий
 │   │   │   ├── KafkaPublisher.py
 │   │   ├── /external     # API-запросы к сторонним сервисам
 │   │   │   ├── PaymentGateway.py
 │   ├── /presentation     # API-интерфейсы
 │   │   ├── /http         # REST API
 │   │   │   ├── OrderController.py
 │   │   ├── /cli          # Консольные команды
 │   │   │   ├── ImportOrders.py
 │   │   ├── /events       # Обработчики событий
 │   │   │   ├── OrderPlacedListener.py
 ├── /customer             # Контекст "Клиенты"
 ├── /billing              # Контекст "Биллинг"
 ├── /shared               # Общий код между контекстами
 │   ├── /kernel           # Базовые интерфейсы и абстракции
 │   ├── /events           # Кросс-доменные события
 │   ├── /utils            # Хелперы и вспомогательные классы
 ├── main.py               # Точка входа
 ├── settings.py           # Конфигурация
 └── requirements.txt      # Зависимости

🛠 Как применять DDD в реальной жизни?

1️⃣ Определить домены — выделить ограниченные контексты и не смешивать их.

2️⃣ Говорить на языке бизнеса — если в компании термин "Клиент", то в коде это тоже "Клиент", а не "UserEntity".

3️⃣ Разделить слои — доменная логика, инфраструктура и интерфейсы не должны жить в одном месте.

4️⃣ Использовать событийную модель — "Заказ создан" → "Биллинг должен выставить счёт" → "Система уведомлений отправляет письмо".

DDD звучит круто, но на практике далеко не всегда оправдывает затраты. Вот основные минусы и подводные камни:

❌ 1. Сложность внедрения

DDD требует глубокого понимания бизнес-процессов. Нужно не просто писать код, а строить архитектуру вокруг бизнеса. Если команда не готова, получится монструозная система с кучей ненужных сущностей.

❌ 2. Избыточность для простых проектов

Если ты делаешь небольшой CRUD-сервис, то DDD – это перебор. Ограниченные контексты, доменные события и инфраструктурные слои только усложнят жизнь.

❌ 3. Высокий порог вхождения

Разработчикам, привыкшим к классическим архитектурам, будет больно. Код становится менее очевидным, а навигация требует знания всех контекстов.

❌ 4. Усложнение коммуникации

Если разделить систему неправильно, то контексты будут постоянно взаимодействовать друг с другом, создавая чрезмерную связанность. В итоге бизнес-логика снова расползётся, а команда утонет в согласованиях.

❌ 5. Зависимость от качества модели

Если на старте неправильно выделить домены, то всё пойдёт по наклонной. Переосмыслить архитектуру на поздних этапах очень дорого.

❌ 6. Замедление старта проекта

DDD требует времени на проектирование, а в реальном мире бизнесу нужны фичи вчера. В стартапах, где важна скорость, проще начать с простого решения, а DDD внедрять постепенно.

🎯 Когда DDD НЕ нужен?

❌ Если проект маленький (обычный CRUD)

❌ Если бизнес ещё сам не понял, как он работает

❌ Если команда не готова поддерживать сложную архитектуру

❌ Если продукту нужно быстро выйти на рынок

✅ Когда DDD полезен?

✔ Если система сложная, с множеством бизнес-правил

✔ Если команда готова работать с доменной моделью

✔ Если кодовая база разрастается и становится неуправляемой

✔ Если модель данных и бизнес-процессы стабильно развиваются

🚀 Итог

DDD — это не просто красивая архитектура, а философия проектирования. Она даёт:

✅ Читаемость кода

✅ Независимость контекстов

✅ Чёткие границы между доменами

Но если всё сделать неправильно, DDD превращается в хаос. 😅 Поэтому главное — не усложнять без необходимости.

Если твой код уже похож на лапшу, возможно, время пересмотреть его структуру. 🏗



DDD — тема непростая, поэтому книги тут играют ключевую роль. Вот парочка отличных источников:

📖 "Domain-Driven Design: Tackling Complexity in the Heart of Software" — Эрик Эванс

Это Библия DDD. Если хочешь понять концепции глубоко — бери и читай. Правда, книга непростая и требует терпения.

📖 "Implementing Domain-Driven Design" — Вон Вернон

Более прикладной вариант. Если после Эванса осталось чувство "что это было?", Вернон поможет разложить все по полочкам.

📝 "DDD Distilled" — тот же Вон Вернон, но в сжатом формате

Если хочешь получить квинтэссенцию DDD без лишней воды — отличный старт.

🎥 Серия лекций от Вон Вернона на YouTube

Можно найти много интересных выступлений, где он объясняет ключевые аспекты DDD.

🛠 Hands-on DDD

На GitHub есть примеры проектов, реализующих DDD, например:

github.com/citerus/dddsample-core (эталонный пример)

github.com/ddd-by-examples/library (пример DDD в библиотеке)

Мой ТГ