Domain-Driven Design: Основы, Ключевые Понятия и Архитектурные Границы

📘 Введение

Domain-Driven Design (DDD) — это не просто набор паттернов, а стратегический подход к проектированию сложных бизнес-приложений. Он помогает выстроить систему вокруг предметной области, а не технических слоёв или внешних фреймворков.

Если у вас болит голова от спагетти-кода, в котором бизнес-логика размазана между контроллерами, сервисами и репозиториями — добро пожаловать в DDD. Здесь царит порядок.


🔑 Главные идеи DDD

  1. Модель предметной области — это сердце системы. Код должен прямо отражать суть бизнес-объектов и правил.
  2. Разделение ответственности — бизнес-логика, прикладная логика, инфраструктура — в разных слоях.
  3. Ubiquitous Language (единый язык) — терминология в коде и среди команды должна быть одинаковой.
  4. Бизнес-решения — в центре. Не база данных, не фреймворк, не API.

🧱 Базовые строительные блоки

📦 Entity (Сущность)

Объект с идентичностью, которая сохраняется при изменении состояния.

Пример: User, Order, Product.

🧩 Value Object (Объект-значение)

Иммутабельный объект без собственной идентичности. Два VO равны, если у них равны значения.

Пример: Email, Money, GeoPoint, PasswordHash.

🔗 Aggregate (Агрегат)

Корневая сущность, которая инкапсулирует всё, что можно менять как единое целое.

  • Состоит из корня (Aggregate Root) и вложенных объектов (entities и VO).
  • Внешний мир может работать только через корень.

Пример: Order — агрегат, включающий OrderItems, ShippingInfo, Total.

📥 Repository

Интерфейс доступа к агрегатам. Абстракция над хранилищем.

Пример: UserRepositoryInterface, OrderRepositoryInterface.

🧠 Domain Service

Содержит бизнес-логику, которая:

  • не относится ни к одной конкретной сущности,
  • зависит от нескольких сущностей.

Пример: TransferService, DiscountCalculator.

🧾 Specification (опционально)

Инкапсулирует условие бизнес-логики (например, “пользователь активен и старше 18”).


🎮 Где живёт логика?

Тип логикиГде размещается
Валидация полейВ Value Object
Бизнес-правила объектаВ Entity
Правила между объектамиВ Domain Service
Генерация токенов, хэши и т.п.В Application или Infrastructure Layer

🗂 Архитектурные слои

src/
├── User/
│   ├── Domain/
│   │   ├── Entity/
│   │   ├── Repository/
│   │   └── ValueObject/
│   ├── Application/
│   │   ├── Command/
│   │   ├── Handler/
│   │   └── DTO/
│   ├── Infrastructure/
│   │   └── Repository/
│   └── UI/
│       └── Controller/
  • Domain — чистый, не зависит ни от кого.
  • Application — orchestration: use-cases, CQRS.
  • Infrastructure — работа с БД, токенами, внешними API.
  • UI — контроллеры, HTTP.

📎 CQRS + DDD

Command Query Responsibility Segregation (CQRS) отлично сочетается с DDD:

  • Command — изменяет состояние (например, RegisterUserCommand).
  • Query — только читает (например, GetUserByIdQuery).

Каждой команде и запросу соответствует Handler, который работает через агрегаты, не смешивает домен и инфраструктуру и не знает про контроллеры.


🧼 Что важно соблюдать

  • Не тяните Doctrine, Request, TokenStorage в Domain.
  • Не стройте сущности с setters. Лучше readonly + фабрики.
  • DTO — только для передачи данных. Никогда не делайте из них доменные модели.
  • Не пишите “умные сервисы” в Application. Логика живёт в домене.

✍️ Заключение

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

Если интересно — могу в следующих статьях раскрыть:

  • как строить агрегаты правильно,
  • как интегрировать DDD с Event Sourcing,
  • или как внедрить CQRS без боли.
Рейтинг
( 2 оценки, среднее 5 из 5 )
Максим Гречушников/ автор статьи
Мне 40 лет, и больше половины жизни я занимаюсь разработкой. За это время я работал с корпоративными системами, highload-проектами, интеграциями, платежными решениями, внутренними платформами и legacy-кодом, который пережил не одного разработчика. Некоторые системы, кажется, переживут и нас. Моя специализация — PHP, Laravel, backend-архитектура, DDD, тестирование, рефакторинг и техническое лидерство. Мне интересны задачи, где нужно соединить код, бизнес, данные, процессы и здравый смысл. Последние годы я много работаю с LLM и AI-инструментами: использую их для проектирования, анализа кода, документации, тестов, ревью, работы с legacy и построения инженерных процессов. Для меня LLM — это не замена разработчику, а усилитель для тех, кто умеет думать системно. В блоге я пишу о Laravel, PHP, архитектуре, тестировании, инженерной практике, управлении разработкой и реальном применении AI в работе программиста.
Понравилась статья? Поделиться с друзьями: