Какой у вас опыт работы с Domain-Driven Design (DDD)?

«Какой у вас опыт работы с Domain-Driven Design (DDD)?» — вопрос из категории Архитектура, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

Стратегический дизайн:

  • Проводил Event Storming и работал с экспертами предметной области для выявления Bounded Contexts.
  • Определял Ubiquitous Language и следил за его соблюдением в коде и документации.
  • Проектировал Context Maps для интеграции между контекстами (Customer/Supplier, Anti-Corruption Layer).

Тактический дизайн:

  • Реализовывал богатые доменные модели с Aggregates, Entities и Value Objects.
  • Использовал Domain Events для реактивности и слабой связности. Например, при подтверждении заказа генерировалось событие OrderConfirmed, которое триггерило процессы в контексте доставки и бухгалтерии.
  • Изолировал доменную логику с помощью Repositories и Domain Services.

Пример Value Object для денежной суммы:

public record Money : IValueObject
{
    public decimal Amount { get; }
    public Currency Currency { get; }

    private Money(decimal amount, Currency currency)
    {
        Amount = amount;
        Currency = currency;
    }

    public static Money Create(decimal amount, Currency currency)
    {
        if (amount < 0) throw new DomainException("Amount cannot be negative.");
        return new Money(amount, currency);
    }

    public Money Add(Money other)
    {
        if (Currency != other.Currency) throw new DomainException("Cannot add different currencies.");
        return Create(Amount + other.Amount, Currency);
    }
}

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