Проектирование доменной модели: с чего начать правильно
Доменная модель начинается не с таблиц и классов, а с правил бизнеса. Пошагово разберём, как выделить границы системы, найти сущности, описать сценарии и проверить модель до написания кода.

Доменную модель можно спроектировать за один рабочий день, если начинать не с базы данных, а с бизнес-сценариев. На выходе у вас будут словарь терминов, границы предметной области, ключевые правила и схема объектов, которую можно обсуждать с заказчиком и командой до первой миграции.
Что подготовить до начала
Материал посвящён предметному моделированию в духе Domain-Driven Design и не привязан к версии конкретного языка или фреймворка. Если модель сразу переносится в код, отдельно проверьте соглашения и ограничения вашей версии Django, Spring, .NET или другого стека: доменная логика не должна зависеть от случайного устройства ORM.
- один конкретный бизнес-процесс, а не весь продукт;
- участника, который принимает решения в этом процессе: специалиста поддержки, менеджера, логиста или владельца продукта;
- описание нескольких реальных сценариев, включая отмену, возврат или отказ;
- доску для схемы и документ, где можно фиксировать спорные термины;
- 60–120 минут на первую сессию и отдельное время на проверку модели по примерам.
Не начинайте с ER-диаграммы. Она показывает структуру хранения, но не объясняет, почему заказ нельзя отменить после передачи в доставку.
Хорошая доменная модель отвечает не на вопрос «какие у нас таблицы», а на вопрос «какие решения система обязана принимать правильно».
Пошаговый порядок работы
1. Ограничьте предметную область одним результатом
Сформулируйте процесс через наблюдаемый результат: «клиент получает оплаченный заказ», «сотрудник закрывает обращение», «компания начисляет комиссию». Уберите всё, что не влияет на этот результат. Доставка, каталог и программа лояльности могут быть соседними областями, но не обязаны входить в одну модель.
Запишите начало и конец процесса, его участников и внешние системы. Если граница не помещается в один абзац, сузьте задачу ещё раз.
Проверка: другой участник встречи может за минуту ответить, где процесс начинается, чем заканчивается и что в него не входит.
2. Соберите язык предметной области
Попросите эксперта рассказать о нескольких реальных случаях и записывайте именно его слова. Отмечайте существительные, действия и условия: «заказ подтверждён», «резерв истёк», «возврат одобрен». Не заменяйте их техническими названиями вроде OrderStatus или processRefund на этом этапе.
Один термин должен означать одно и то же внутри выбранной границы. Если менеджер называет «заказом» заявку до оплаты, а склад так называет только оплаченный документ, это не стилистическая мелочь, а конфликт модели.
Проверка: в словаре нет двух слов для одного состояния и одного слова с двумя разными смыслами без явной пометки.
3. Опишите сценарии через события и решения
Для каждого процесса составьте короткую цепочку: что произошло, кто принял решение, какое правило сработало и что изменилось. Например: «покупатель оплатил заказ → система проверила доступность товара → резерв создан». Затем добавьте отрицательные варианты: товар уже зарезервирован, платёж отменён, срок резерва закончился.
Событие описывает факт в прошлом. Команда или действие выражает намерение: «создать резерв», «отменить заказ». Это разделение помогает не смешивать входящий запрос с результатом его выполнения.
Проверка: для каждого важного сценария есть хотя бы один успешный и один отказной путь, а причины отказа сформулированы словами эксперта.
4. Отделите сущности от значений
Сущность сохраняет идентичность во времени: заказ может изменить статус, но остаётся тем же заказом. Объект-значение описывает характеристику без собственной идентичности: денежная сумма, адрес, период или номер телефона. Если два адреса содержат одинаковые поля, для бизнес-правила они могут быть равны без отдельного идентификатора.
Не превращайте каждое поле в самостоятельный объект. Выделяйте объект-значение там, где у него есть собственное правило: сумма не может быть отрицательной, период не может заканчиваться раньше начала, адрес должен пройти проверку формата.
Проверка: для каждого объекта понятно, как определить его идентичность и какие изменения ему разрешены.
5. Найдите границы согласованности
Теперь соберите связанные объекты вокруг правила, которое должно выполняться целиком. Заказ и его строки могут образовывать одну группу, если нельзя изменить строку так, чтобы нарушить итоговую сумму. Не объединяйте в неё склад, оплату и доставку только потому, что они участвуют в одном пользовательском сценарии.
Такая группа называется агрегатом1. Внешний код обращается к её корню, а правила внутри проверяются в одной операции. Чем крупнее агрегат, тем больше данных приходится блокировать или синхронизировать; слишком мелкий агрегат, наоборот, оставляет важное правило без единой точки контроля.
Проверка: для каждого инварианта понятно, какой объект его проверяет и какая операция не может оставить модель в запрещённом состоянии.
6. Проверьте внешние связи и контексты
Соседняя система может использовать те же слова, но вкладывать в них другой смысл. Для бухгалтерии «заказ» может быть основанием для документа, для склада — набором позиций к отбору, для доставки — отправлением. Не пытайтесь сделать один универсальный класс, который удовлетворит всем трём сторонам.
Зафиксируйте, что передаётся между областями: идентификатор, событие, снимок данных или запрос. Отдельно отметьте владельца каждого правила. Инвалидация кеша и выбор брокера сообщений здесь не разбираются: это отдельные технические решения.
Проверка: для каждой интеграции указаны источник истины, формат сообщения и действие при задержке или отказе внешней системы.
7. Прогоните модель по реальным примерам
Возьмите пять–десять операций из журналов, заявок или интервью. Для каждой покажите, какая команда поступает, какой объект меняется, какое правило срабатывает и какое событие появляется. Если для объяснения приходится добавлять исключение «только в этом случае», модель ещё не готова.
На этом этапе можно создавать классы, таблицы и API. До него код часто закрепляет спорные термины, а исправление модели превращается в переименование колонок, миграции и изменение контрактов.
Проверка: команда может пройти по примерам без устных пояснений, которых нет на схеме или в описании правил.
Если не получилось
У доменной модели нет стандартного сообщения об ошибке, как у компилятора. Проблема проявляется в разговоре, ревью и примерах данных. Ищите такие сигналы:
- «У нас всё является сущностью». Вернитесь к вопросу об идентичности. Если объект не меняется во времени и сравнивается по значениям, это кандидат на объект-значение.
- «Статус можно поставить любым значением». Выпишите переходы между состояниями и запретите операции, которые нарушают бизнес-правила. Набор строк в базе сам по себе моделью не является.
- «Один и тот же заказ выглядит по-разному в трёх командах». Разделите контексты и назовите преобразование между ними. Универсальный словарь обычно скрывает несовместимые правила.
- «Для одной операции нужно обновить пять сервисов сразу». Проверьте границы агрегатов и не требуйте синхронной согласованности там, где достаточно события и последующей обработки.
- «Эксперт не понимает схему». Уберите технические классы, индексы и таблицы. Верните формулировки реального процесса и проверьте их на конкретном примере.
Не исправляйте все замечания добавлением новых сущностей. Сначала выясните, какое правило или решение модель должна сделать явным.
Сноска. Агрегат — граница согласованности в доменной модели: набор объектов, который изменяется через один корневой объект и должен сохранять свои правила после каждой операции.
Что делать дальше
Перенесите словарь и сценарии в репозиторий рядом с кодом, назначьте владельца терминов и добавьте тесты на отказные пути. После запуска смотрите не только на время ответа API, но и на количество отклонённых команд, повторных операций, конфликтов при обновлении и ручных исправлений. Эти показатели покажут, где модель расходится с реальным процессом.
Следующий практический шаг — выбрать один агрегат и реализовать для него две операции: успешную и запрещённую. Если правило нельзя выразить без обращения к пяти таблицам или скрытого состояния в контроллере, вернитесь к границам модели, а не маскируйте проблему новым слоем кода.
Карточки для маркетплейсов: Таблица товаров и папка фотографий на входе — комплект слайдов и описаний на выходе, по требованиям Wildberries и Ozon.
Спросить за 5 ₽Источники: Domain-Driven Design — Martin Fowler, Domain analysis — Microsoft Azure Architecture Center
Частые вопросы
Нужно ли изучать Domain-Driven Design перед проектированием модели?
Начинать с сущностей или с базы данных?
Можно ли сделать одну доменную модель для всего продукта?
Что делать, если эксперты используют противоречивые термины?
Нужно ли сразу выделять микросервисы по доменным границам?
Как понять, что модель уже достаточно хороша?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.