Backend Typescript 1.0.0 Help

Доменная модель

Зачем нужна доменная модель?

Доменная модель — это мыслительная конструкция, описывающая предметную область, её понятия, правила и ограничения в виде взаимосвязанных объектов и процессов. Её цель — чтобы программная система отражала реальные правила бизнеса, а не только структуру данных или технические детали.

  • Модель делает явными термины и правила, снижая разрыв между бизнесом и разработкой.

  • Модель определяет инварианты — то, что «нельзя нарушать никогда».

  • Модель задаёт границы изменений: где можно расширять поведение, а где менять нельзя.

Базовые понятия доменного анализа

Предметная область и границы смысла

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

Единый язык (Ubiquitous Language) — согласованные определения терминов, которыми одинаково пользуются и разработчики, и эксперты домена.

Модель не равна схеме БД

Доменная модель описывает правила и поведение. Схема хранения — вторична и может меняться без изменения смысла. Не подменяйте модель таблицами: колонки не выражают инварианты и политики.

Строительные блоки модели (тактические паттерны)

Сущность

Сущность — объект, чья идентичность важнее текущих свойств. Идентичность постоянна на всём жизненном цикле.

Значение (Value Object)

Значение — неизменяемый объект без собственной идентичности, полностью описываемый своими полями (например, денежная сумма с валютой). Два значений равны, если равны их поля.

Агрегат и корень агрегата

Агрегат — когерентный кластер сущностей и значений с общими инвариантами. Корень агрегата — единственная точка внешнего доступа и изменение состояния внутри агрегата допустимо только через него.

Доменные события

Доменное событие — произошедший факт в терминах домена («Оплата проведена», «Заказ отменён»). Событие фиксирует изменение существенного состояния и служит триггером для реакций других частей модели.

Доменные службы и политики

Доменная служба — место для поведения, которое неестественно «привинчивать» к одной сущности (например, расчёт скидки по набору правил). Политика — правило принятия решений внутри домена, независимое от инфраструктуры.

Стратегический уровень DDD

Ограниченные контексты и карта контекстов

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

Согласованность между контекстами

Строгая согласованность удобна, но дорого стоит при масштабировании. На практике часто применимо согласование со временем (eventual consistency) через события и политики повторов.

Подходы к разработке вокруг модели

DDD — моделирование, от языка к коду

Domain-Driven Design (DDD) — подход, при котором дизайн системы ведут доменные понятия и правила. Он включает стратегические решения (контексты, их отношения) и тактические (сущности, значения, агрегаты, события).

  • Сначала язык и сценарии, потом структуры и границы.

  • Инварианты — внутри агрегатов; взаимодействия — через события и политики.

  • Эволюция модели — нормальный процесс: пересогласовывайте термины по мере обучения домену.

TDD — проверяем поведение модели

Test-Driven Development (TDD) — цикл «красный → зелёный → рефакторинг». Тест формулирует ожидаемое поведение в терминах домена, минимальная реализация удовлетворяет тест, затем структура упрощается без изменения поведения.

  • Пишите примеры в терминах домена, а не технических деталей.

  • Тестируйте инварианты агрегата: «это невозможно», «это всегда так».

  • Фиксируйте контракты событий: что гарантируется после факта.

Given: Баланс счёта = 100 When: Списать 30 Then: Баланс = 70, событие "СписаниеПроведено", инвариант "Баланс >= 0" сохранён

EDD — событийно-ориентированное проектирование

EDD (Event-Driven Design/Development) — мышление фактами: система выражается как последовательности значимых событий и реакций на них. Сначала выявляются события и причинно-следственные связи, затем — команды, политики и агрегаты, которые делают события возможными и законными.

  • События описывают «что уже произошло», команды — «что намерены сделать».

  • События помогают разорвать жёсткие связи и согласовывать контексты.

  • EDD хорошо выявляет скрытые инварианты и зависимости во времени.

Как из предметной области получить модель (пошагово)

  • Собрать язык: выписать термины, их определения и примеры. Уточнить неоднозначности.

  • Нарисовать сценарии: кто что делает, какие результаты важны, какие ситуации запрещены.

  • Выявить события: что фиксируем как «случилось»; какие инварианты должны быть верны до/после.

  • Сгруппировать в агрегаты: чтобы внутри можно было строго поддерживать правила без внешних зависимостей.

  • Определить контексты: где язык стабилен; как контексты взаимодействуют (источник истины, переводы понятий).

  • Проверить TDD-примерами: формализовать кейсы и граничные условия; зафиксировать контракты событий.

  • Эволюционировать: упрощать, переименовывать, разделять контексты по мере обучения домену.

Инварианты, время и согласованность

Инварианты бывают локальные (внутри агрегата) и глобальные (на уровне контекста/системы). Локальные защищаются строго, глобальные согласуются через процессы и события.

  • Неизменяемость значений упрощает разум о прошлом: факты не переписываются, добавляются новые события.

  • Идемпотентность реакций на события снижает риск дубликатов и повторов.

  • Временные зависимости: учитывайте порядок и дедлайны — это часть доменных правил.

Команды, запросы и CQRS как мыслительная модель

Команды меняют состояние (инициируют поведение агрегатов). Запросы читают состояние. Разделение ответственности (идея CQRS) упрощает модель: мыслите отдельно о «как меняем» и «как читаем».

Анти-паттерны и частые ошибки

  • Агрегат-«мешок данных»: нет инвариантов, всё редактируется где угодно. Итог — состояние «вроде допустимо», но бизнес нарушен.

  • Микро-агрегаты: каждое поле — свой агрегат. Итог — бесконечные согласования и сложность процессов.

  • Тесты-мокеты внутренностей: ломаются при любом рефакторинге, не ловят нарушения правил.

  • Событийный шум: событие на каждый чих. Важные факты тонут в логах.

  • Неясные границы контекстов: один термин означает разное — дефекты на стыках неизбежны.

Мини-эталоны формулировок (для практики мышления)

Правило (инвариант): — Сумма возврата <= сумме оплаченных позиций Нарушение невозможно при корректном использовании агрегата "Возврат". Событие: — "ДоговорПодписан": после него "СтатусДоговора = Активен" и "ДатаПодписания установленa". Команда: — "ПодписатьДоговор" требует предварительного состояния "Статус = ГотовКПодписанию".
Last modified: 01 October 2025