Ответ
Domain-Driven Design (DDD) предлагает набор концепций и паттернов (строительных блоков) для проектирования сложных программных систем, ориентированных на предметную область бизнеса.
Ключевые строительные блоки:
-
Entity (Сущность) Объект, обладающий уникальным идентификатором и жизненным циклом. Его идентичность важна, даже если атрибуты меняются. Пример:
ПользовательсuserId. -
Value Object (Объект-значение) Неизменяемый (immutable) объект, который определяется своими атрибутами, а не идентификатором. Два Value Object с одинаковыми атрибутами считаются равными. Пример:
Адрес(улица, город),Деньги(сумма, валюта). -
Aggregate (Агрегат) Кластер связанных объектов (сущностей и объектов-значений), который рассматривается как единое целое для изменения данных. У агрегата есть Aggregate Root (корень) — сущность, которая является единственной точкой входа для всех операций с агрегатом и следит за соблюдением бизнес-правил (инвариантов).
-
Repository (Репозиторий) Абстракция, имитирующая коллекцию объектов в памяти. Скрывает детали хранения (база данных, API) и предоставляет интерфейс для получения и сохранения агрегатов.
-
Domain Service (Сервис домена) Содержит доменную логику, которую сложно отнести к какой-либо конкретной сущности или объекту-значению. Часто координирует работу нескольких агрегатов.
-
Domain Event (Событие домена) Объект, который представляет собой что-то значимое, произошедшее в предметной области. Пример:
ЗаказОформлен,ПользовательЗарегистрирован.
Пример Агрегата Order:
# Value Object
class OrderItem:
def __init__(self, product_id: str, quantity: int, price: float):
if quantity <= 0:
raise ValueError("Quantity must be positive")
self.product_id = product_id
self.quantity = quantity
self.price = price
# Aggregate Root
class Order:
def __init__(self, order_id: str, customer_id: str):
self.id = order_id
self.customer_id = customer_id
self._items: list[OrderItem] = []
self.status = "created"
# Метод корня агрегата контролирует добавление элементов
# и защищает инвариант (например, нельзя добавить товар в оплаченный заказ)
def add_item(self, item: OrderItem):
if self.status != "created":
raise Exception("Cannot add items to a completed order")
self._items.append(item)
def complete_order(self):
self.status = "completed"