← Назад к вопросам

Что такое агрегат в DDD?

2.0 Middle🔥 251 комментариев
#Микросервисы и архитектура

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое Агрегат в DDD (Domain-Driven Design)?

Агрегат — это один из ключевых паттернов в Domain-Driven Design, предназначенный для управления сложностью бизнес-модели. В своей основе агрегат представляет собой кластер связанных объектов (сущностей и значений), которые рассматриваются как единое целое для целей изменения данных. Основная задача агрегата — обеспечить консистентность и инкапсуляцию бизнес-правил внутри четко определенных границ транзакций.

Ключевые характеристики и принципы агрегата

1. Корень агрегата (Aggregate Root)

Каждый агрегат имеет единственный корень агрегата — специальную сущность, которая служит единственной точкой доступа для внешнего мира. Все изменения состояния агрегата должны происходить только через корень.

// Пример: агрегат "Order" с корнем OrderAggregate
type OrderAggregate struct {
    orderID      string           // Идентификатор агрегата
    customerID   string
    items        []OrderItem      // Сущности внутри агрегата
    status       OrderStatus      // Значения внутри агрегата
    totalPrice   decimal.Decimal
}

// Корень управляет доступом к внутренним сущностям
func (o *OrderAggregate) AddItem(productID string, quantity int, price decimal.Decimal) error {
    // Бизнес-правила внутри агрегата
    if o.status != OrderStatusOpen {
        return errors.New("cannot add items to closed order")
    }
    // Корень изменяет внутренние сущности
    o.items = append(o.items, OrderItem{
        productID: productID,
        quantity:  quantity,
        price:     price,
    })
    o.calculateTotal()
    return nil
}

2. Инкапсуляция бизнес-правил

Все бизнес-правила и инварианты (условия консистентности) должны проверяться внутри агрегата. Внешние компоненты не могут напрямую изменять внутренние сущности — только через методы корня.

3. Границы транзакций

Агрегат определяет границы для операций изменения данных. В рамках одной транзакции может быть изменен только один агрегат. Это критично для распределенных систем и микросервисов.

4. Неразрывная целостность

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

Почему агрегаты важны в Go разработке?

В контексте Go агрегаты помогают структурировать код в соответствии с бизнес-доменом, что особенно важно при разработке микросервисов:

  • Управление сложностью: Большие доменные модели разбиваются на управляемые агрегаты с четкими обязанностями.
  • Контроль изменений: Агрегаты предотвращают рассеянную логику бизнес-правил по всему коду.
  • Оптимизация транзакций: Ясные границы помогают правильно организовать транзакции и избегать проблем с конкурентным доступом.
  • Тестирование: Агрегаты легко тестировать как единые модули с замкнутой логикой.

Практический пример в Go: банковский счет

// Агрегат BankAccount с корнем Account
type Account struct {
    accountNumber string
    balance       decimal.Decimal
    transactions  []Transaction // Внутренняя сущность
    isClosed      bool
}

// Корень агрегата обеспечивает инкапсуляцию
func (a *Account) Deposit(amount decimal.Decimal) error {
    if a.isClosed {
        return errors.New("account is closed")
    }
    if amount.LessThan(decimal.NewFromFloat(0)) {
        return errors.New("deposit amount must be positive")
    }
    // Изменение состояния внутри агрегата
    a.balance = a.balance.Add(amount)
    a.transactions = append(a.transactions, Transaction{
        type:   "deposit",
        amount: amount,
        time:   time.Now(),
    })
    return nil
}

// Внешний код не может напрямую изменить balance или transactions

Ключевые рекомендации по работе с агрегатами

  • Маленькие агрегаты: Следует создавать небольшие агрегаты — это уменьшает конфликты транзакций и повышает производительность.
  • Идентификатор корня: Корень агрегата должен иметь глобально уникальный идентификатор, который ссылаются другие агрегаты.
  • Ссылки через идентификаторы: Агрегаты должны ссылаться друг на друга только по идентификаторам корней, не по объектам.
  • Инварианты при каждом изменении: Корень должен проверять все бизнес-правила при каждом изменении состояния.

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