Ответ
Агрегат в Domain-Driven Design (DDD) — это кластер связанных объектов домена, которые можно рассматривать как единое целое. Главная задача агрегата — обеспечивать целостность данных и соблюдение бизнес-правил (инвариантов) внутри своей транзакционной границы.
У каждого агрегата есть Корень Агрегата (Aggregate Root) — это сущность внутри агрегата, которая является единственной точкой входа для всех внешних обращений. Любые изменения в объектах внутри агрегата должны происходить только через методы его корня.
Ключевые принципы:
- Защита инвариантов: Корень агрегата отвечает за то, чтобы любое изменение не нарушало бизнес-правила. Например, нельзя добавить в заказ товар, которого нет на складе.
- Транзакционная целостность: Изменения в агрегате сохраняются атомарно. Либо все изменения внутри него успешны, либо ни одно из них не применяется.
- Ссылки по идентификатору: Внешние объекты могут ссылаться только на корень агрегата. Прямые ссылки на внутренние объекты агрегата запрещены, чтобы не нарушать его целостность.
Пример на Go:
// Order является Корнем Агрегата
type Order struct {
ID uuid.UUID
CustomerID uuid.UUID
Items []OrderItem
Status string
}
// OrderItem - часть агрегата, управляемая через Order
type OrderItem struct {
ProductID uuid.UUID
Price float64
Quantity int
}
// Метод на корне агрегата для добавления элемента.
// Он контролирует соблюдение бизнес-правил.
func (o *Order) AddItem(item OrderItem) error {
if o.Status == "Completed" {
return errors.New("нельзя добавить товар в завершенный заказ")
}
// Другие проверки, например, на максимальное количество товаров
o.Items = append(o.Items, item)
return nil
} Ответ 18+ 🔞
А, вот эта штука, агрегат в DDD! Ну, это ж классика, блядь, как Герасим с Муму, только в мире кода. Сейчас объясню, чтобы не было, как у того немого — «му-му», а нихуя не понятно.
Представь себе, что у тебя есть заказ в интернет-магазине. Это не просто бумажка с номером, ёпта. Это целая вселенная, блядь! Там и товары, и цены, и статусы, и скидки, и чёрт в ступе. Так вот, Агрегат — это и есть такая вот законченная, блядь, вселенная, которую ты должен держать в целости и сохранности. Как крепость, сука.
А в центре этой крепости сидит Корень Агрегата — главный по тарелочкам, ёбаный в рот. Он один имеет право говорить с внешним миром. Хочешь что-то в заказе поменять? Иди нахуй к корню, через его методы. Не лезь напрямую к внутренним сущностям, а то получишь, как тот князь с лестницы — пиздык ногами вниз!
Зачем этот цирк, спросишь? А затем, чувак, чтобы не было пиздеца! Чтобы бизнес-правила не нарушались. Нельзя, например, добавить в завершённый заказ товар. Или нельзя сделать скидку больше 100%, а то мы в минус уйдём, блядь. Корень агрегата — это такой злобный, блядь, максималист, как Герасим, который следит, чтобы вся эта хуйня внутри его владений была консистентной. Либо всё правильно, либо нихуя.
И сохраняется это всё атомарно. Либо весь агрегат записался, либо сгорел в аду. Никаких полумер, «ой, товар добавился, а статус не обновился». Такого не должно быть, иначе — волнение ебать, доверия к системе ноль.
Смотри, как это выглядит в коде, на примере заказа. Блок кода не трогаю, оставляю как есть, но поясню вокруг, блядь:
// Order — это наш Корень, главный мудак в этой истории
type Order struct {
ID uuid.UUID
CustomerID uuid.UUID
Items []OrderItem // Это его внутренние объекты, как Муму
Status string
}
// OrderItem — просто часть агрегата, без прав голоса
type OrderItem struct {
ProductID uuid.UUID
Price float64
Quantity int
}
// А вот метод на корне! Единственный законный способ что-то сделать.
// Попробуй добавить товар в завершённый заказ — получишь по ебалу ошибкой.
func (o *Order) AddItem(item OrderItem) error {
if o.Status == "Completed" {
return errors.New("нельзя добавить товар в завершенный заказ") // Вот тебе, жопа с ручками!
}
// Тут могут быть другие проверки, инварианты, бизнес-логика...
o.Items = append(o.Items, item)
return nil
}
Видишь? Всё контролируется. Никаких прямых манипуляций с o.Items извне. Хочешь изменить — иди через корень. А внешние системы ссылаются только на ID заказа, а не лезут в его кишки. Красота, блядь!
Вот так и живём. Создаём эти маленькие, самодостаточные крепости-агрегаты, чтобы не превратить всю систему в один большой, блядь, бардак, где каждый тянет одеяло на себя. Иначе будет, как в той сказке — «ядра — чистый изумруд», а на деле — пиздец полный.