Содержание

Domain-Driven Design (DDD, предметно-ориентированное проектирование) — это подход, при котором структура кода повторяет устройство бизнеса: разработчики и эксперты говорят на одном языке, система делится на части по предметным областям, а самые важные правила живут в коде явно, а не размазаны по контроллерам. DDD окупается в продуктах со сложной бизнес-логикой и избыточен для простых сайтов и CRUD-приложений.

Разберём ключевые идеи DDD без сложных терминов, когда подход оправдан и как начать применять его постепенно.

Что такое DDD?

DDD — это набор практик для проектов, где главная сложность не в технологиях, а в самой предметной области: тарифах, правилах начисления, логистике, финансовых операциях. Идея простая — сначала глубоко понять бизнес вместе с его экспертами, а потом выразить это понимание в коде так, чтобы оно было видно.

Основные идеи:

  • единый язык — одни и те же термины в разговорах, документации и коде;
  • ограниченные контексты — система делится на части с собственной моделью и словарём;
  • агрегаты — группы объектов, которые меняются вместе и охраняют свои правила;
  • доменные события — значимые факты бизнеса: «заказ оплачен», «договор подписан».

Зачем нужен единый язык?

Единый язык нужен, чтобы бизнес и разработчики понимали друг друга без перевода. Если менеджер говорит «бронь», аналитик — «резерв», а в коде — Hold, то каждая задача обрастает недопониманием, а ошибки появляются на стыке формулировок.

Как создают единый язык:

  1. Проводят сессии с экспертами и выписывают ключевые термины процесса.
  2. Для каждого термина фиксируют точное определение и границы.
  3. Используют эти слова в задачах, документации, названиях классов и таблиц.
  4. Когда смысл термина меняется, меняют и код.

Хорошее место для такой работы — этап исследования перед разработкой, подробнее в статье discovery-фаза, а также в техническом задании.

Рука отмечает точки на карте красными булавками Фото: Unsplash

Что такое ограниченный контекст?

Ограниченный контекст — это часть системы, внутри которой у каждого термина одно значение. Слово «клиент» в продажах означает потенциального покупателя со сделкой, в бухгалтерии — плательщика с реквизитами, в поддержке — человека с обращениями. Попытка описать всё это одной моделью порождает огромный класс, который никто не может безопасно менять.

Контекст Что значит «клиент» Что важно
Продажи Лид или компания в воронке Этап сделки, менеджер, источник
Биллинг Плательщик Реквизиты, тариф, задолженность
Поддержка Автор обращений История тикетов, приоритет
Доставка Получатель Адрес, окно доставки, телефон

Контексты общаются через явные интерфейсы и события, а не через общие таблицы. Именно они часто становятся естественными границами модулей или сервисов — об этом статья монолит или микросервисы.

Что такое агрегаты и доменные события?

Агрегат — это группа объектов, которые меняются только вместе и через один вход, чтобы бизнес-правила нельзя было обойти. Заказ с позициями — агрегат: нельзя добавить позицию в оплаченный заказ, и это правило проверяется в одном месте, а не в каждом контроллере.

final class Order
{
    public function addItem(Product $product, int $quantity): void
    {
        if ($this->status !== OrderStatus::Draft) {
            throw new OrderAlreadyPlaced($this->id);
        }

        $this->items[] = new OrderItem($product->id, $product->price, $quantity);
    }

    public function markPaid(Payment $payment): void
    {
        $this->status = OrderStatus::Paid;
        $this->recordEvent(new OrderPaid($this->id, $payment->amount));
    }
}

Доменное событие OrderPaid сообщает другим контекстам — складу, биллингу, уведомлениям — о факте оплаты. Им не нужно знать, как устроен заказ внутри, а события удобно обрабатывать асинхронно — подробнее в статьях очереди задач и Kafka или RabbitMQ.

Когда DDD оправдан, а когда избыточен?

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

DDD помогает, если:

  • в продукте сложные расчёты: тарифы, скидки, начисления, лимиты;
  • над системой работает несколько команд с разными зонами ответственности;
  • эксперты и разработчики регулярно понимают требования по-разному;
  • изменения в одной части неожиданно ломают другие.

DDD избыточен, если:

  • приложение — в основном формы и списки без сложных правил;
  • проект короткий и не будет развиваться;
  • в команде один-два разработчика и простая предметная область.

Как начать применять DDD постепенно?

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

  • проведите одну-две сессии с экспертами и зафиксируйте единый язык;
  • нарисуйте карту контекстов и связей между ними;
  • выберите самую сложную и изменчивую область и начните с неё;
  • выносите правила в агрегаты и покрывайте их модульными тестами — подробнее в статье какие автотесты нужны продукту.

Коротко

  • DDD строит код вокруг устройства бизнеса, а не вокруг технологий.
  • Единый язык убирает недопонимание между бизнесом и разработкой.
  • Ограниченные контексты делят систему на части с собственными моделями.
  • Агрегаты охраняют бизнес-правила, доменные события связывают контексты.
  • Подход окупается при сложной логике и избыточен для простых CRUD-проектов.

Частые вопросы

  • Нужен ли DDD для микросервисов?

    Не обязательно, но ограниченные контексты из DDD — хороший способ найти границы сервисов. Сервисы, нарезанные по техническим слоям, а не по предметной области, обычно получаются сильно связанными.

  • Можно ли применять DDD в Laravel?

    Да. Laravel не мешает выделять модули по предметным областям, писать доменную логику в отдельных классах и использовать события. Важно не превращать Eloquent-модели в свалку всей бизнес-логики.

  • Сколько времени нужно, чтобы внедрить DDD?

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