Sobes.tech
Назад к вопросам
Junior — Middle
54

Можете объяснить концепцию разработки, ориентированной на доменную модель?

Ответ от нейросети

sobes.tech AI

Что хотят услышать интервьюеры:

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

Определение:

Разработка, ориентированная на доменную модель, — это способ проектирования, при котором основная логика приложения выражается через объекты и правила предметной области. Вместо того чтобы держать бизнес-правила в контроллерах, сервисах или SQL-запросах, их помещают в доменные сущности, value objects, доменные сервисы и связанные с ними правила.

Главная идея: код должен отражать терминологию и ограничения реального бизнеса.

Пример использования:

Например, в системе интернет-магазина есть доменная модель Order, OrderItem, Money. Правило “нельзя оформить заказ с отрицательной суммой” или “нельзя добавить товар в заказ после его оплаты” должно жить в самой доменной модели, а не размазываться по API-слою.

from dataclasses import dataclass, field

@dataclass(frozen=True)
class Money:
    amount: int

    def __post_init__(self):
        if self.amount < 0:
            raise ValueError("Сумма не может быть отрицательной")

@dataclass
class Order:
    items: list[Money] = field(default_factory=list)
    paid: bool = False

    def add_item(self, price: Money) -> None:
        if self.paid:
            raise ValueError("Нельзя изменять оплаченный заказ")
        self.items.append(price)

    def total(self) -> Money:
        return Money(sum(item.amount for item in self.items))

    def pay(self) -> None:
        if not self.items:
            raise ValueError("Нельзя оплатить пустой заказ")
        self.paid = True

Пояснение кода:

  • Money — объект значения: он хранит сумму и сам проверяет инвариант, что значение не может быть отрицательным.
  • Order — доменная сущность: у нее есть состояние и поведение, связанное с правилами бизнеса.
  • Метод add_item() запрещает изменение уже оплаченного заказа.
  • Метод pay() не позволяет оплатить пустой заказ.
  • Бизнес-ограничения находятся рядом с данными, которые они защищают, поэтому их сложнее нарушить из внешнего кода.

Ключевые моменты:

  • Доменная модель описывает бизнес-логику через предметные понятия, а не через технические детали.
  • Правила и ограничения должны жить в модели, чтобы быть централизованными и понятными.
  • Основные строительные блоки: сущности, объекты-значения, доменные сервисы, инварианты.
  • Подход особенно полезен, когда доменная область сложная и правила часто меняются.
  • Хорошая доменная модель улучшает читаемость, тестируемость и поддержку кода.
  • Не стоит путать с простой “моделью данных”: доменная модель должна содержать поведение, а не только поля.