Агрегаты и сущности

Тема дорожной карты · Software Architecture

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

Как это работает

Идентифицируйте границы агрегата, задавая себе вопрос: 'Какое состояние должно меняться вместе для поддержания инвариантов?'. Например, заказ (Order) и его элементы заказа (OrderItems) образуют один агрегат, потому что элементы заказа не могут существовать без заказа, а статус заказа зависит от элементов заказа. Таким образом, изменения в элементах заказа автоматически обновляют статус заказа, обеспечивая целостность данных.

Aggregate Root — это единственный объект, на который внешний код может держать ссылку. Вся доступность к внутренним объектам осуществляется через Aggregate Root. Например, если у вас есть Order как Aggregate Root, все операции над OrderItems должны проходить через Order.add_item(). Это позволяет контролировать доступ к внутренним объектам и поддерживать целостность данных.

Граница агрегата — это транзакционная единица: один агрегат = одна транзакция. Это означает, что все изменения, внесенные в агрегат, должны быть выполнены в рамках одной транзакции, чтобы гарантировать целостность данных. Если граница агрегата нарушается, возникают проблемы с консистентностью данных.

Когда применять

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

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

Типичные ошибки

(1) Агрегаты слишком большие — один гигантский агрегат из 30 сущностей; граница транзакции становится слишком грубой, что приводит к увеличению контеншена (contention). Это может привести к замедлению производительности и усложнению управления транзакциями.

(2) Агрегаты слишком маленькие — отделение Order от его OrderItems заставляет две транзакции поддерживать консистентность order-total; race conditions появляются. Это может привести к неожиданным результатам и сложностям в поддержании целостности данных.

(3) Прямая манипуляция child'ами — код достаёт внутрь агрегата для модификации child без прохода через root; инварианты агрегата обходятся. Это может привести к нарушению целостности данных и сложностям в поддержании бизнес-правил.

Связанные понятия

Полезные ресурсы