DDD легко испортить двумя способами. Первый — превратить его в технический культ, где все обсуждают aggregates, entities и bounded contexts, но почти не связывают это с реальной системой. Второй — решить, что это вообще “история для архитекторов и разработчиков”, а аналитике достаточно бизнес-требований, процессов и glossary.
На практике обе крайности одинаково вредны. Если DDD превращается в набор терминов, он перестаёт помогать проектированию. Если аналитика игнорирует доменную модель, архитектура получает слишком позднюю и слишком техническую картину предметной области. В результате границы контекстов определяются не смыслом системы, а удобством текущей реализации или историей оргструктуры.
Поэтому полезно смотреть на DDD спокойно: не как на религию и не как на специфическую технику проектирования “только для сложного enterprise”, а как на способ точнее видеть домен и раньше замечать, где предметная область сама начинает подсказывать архитектурные границы.
В прошлой статье мы отбирали архитектурные драйверы. Теперь следующий вопрос: какая доменная модель выдержит эти ограничения? Продолжим серию на примере лунной базы и разберём, чем DDD действительно полезен аналитику, если убрать лишний пафос и сосредоточиться на вопросе: как сделать так, чтобы доменная модель помогала архитектуре, разработке и эксплуатации говорить на одном языке.
В статье
- Зачем аналитику вообще нужен DDD
- Почему доменная модель важнее терминов
- Ubiquitous language: где он рождается и почему без него всё расползается
- Bounded context: не про коробки, а про границы смысла
- Лунная база: какие контексты там естественны
- Контекстная карта: контексты обмениваются смыслом
- Где аналитика помогает DDD, а где может его испортить
- Короткий checklist перед разметкой доменной модели
- Что дальше
Зачем аналитику вообще нужен DDD
Аналитику DDD нужен не для того, чтобы уверенно произносить aggregate, entity или anti-corruption layer. Эти термины пригодятся позже, но не с них начинается польза DDD. Он нужен, чтобы раньше видеть:
- где разные участники системы говорят об одном и том же разными словами;
- где одно слово скрывает несколько разных смыслов;
- где “единая модель” на самом деле натягивает друг на друга несовместимые процессы;
- где границы ответственности в домене не совпадают с тем, как система сейчас организована технически.
Хорошая доменная модель нужна не только разработке. Она нужна всей системе принятия решений:
- аналитике — чтобы не писать требования к “средней температуре по больнице”;
- архитектуре — чтобы не строить границы сервисов поверх терминологической каши;
- разработке — чтобы не компенсировать неясность домена техническими костылями;
- инженерам домена и эксплуатации — чтобы не обнаружить позже, что система красиво автоматизирует неправильную картину реальности.
Почему доменная модель важнее терминов
DDD очень легко начать воспринимать как словарь правильных понятий. Но проблема почти никогда не в том, знает ли команда термин bounded context. Проблема в том, различает ли команда:
- запас как “общее количество”;
- резерв как “недоступное к обычному распределению количество”;
- критичный резерв как ресурс, который нельзя тратить теми же правилами, что остальные;
- телеметрию как поток сигналов;
- операционное состояние как данные для принятия решения;
- команду как намерение;
- действие как факт исполнения.
Если эти различия не проговорены, язык проекта начинает врать. А когда язык проекта врёт, архитектура рано или поздно начинает закреплять эту ошибку в схемах, API и данных.
Поэтому доменная модель полезна не как набор сущностей для ER-диаграммы, а как способ удержать различия, которые для системы реально важны.
Вернёмся к сквозному сценарию серии: связь с Землёй пропала на 40 минут, а энергобюджет просел. Именно в такой момент дороже всего обходится, если одно слово в разных контурах значит разное. Посмотрите, как расходится смысл одних и тех же терминов:
| Термин | Жизнеобеспечение | Логистика | Энергетика | Наземное планирование |
|---|---|---|---|---|
| «резерв» | неприкосновенный запас воздуха/воды на аварию | складской буфер под будущий расход | зарезервированная мощность под пик | страховой объём, заложенный в прогноз поставок |
| «состояние базы» | параметры в пределах порогов | остатки и движение запасов | баланс генерации и потребления | сводный прогноз по всей базе |
| «критично» | угроза жизни прямо сейчас | риск исчерпать запас к сроку | риск отключения нагрузок | срыв долгосрочного плана миссии |
Если в сценарии просадки энергии наземный контур под «резервом» понимает страховой объём поставок, а жизнеобеспечение — неприкосновенный аварийный запас, то одно и то же решение «израсходовать резерв» будет означать диаметрально разное. Доменная модель нужна ровно затем, чтобы такие расхождения были видны до того, как они закрепятся в API и данных.
Ubiquitous language: где он рождается и почему без него всё расползается
Ubiquitous language часто описывают слишком академично. На практике это просто рабочий общий язык, на котором:
- аналитика пишет требования;
- архитекторы обсуждают границы;
- разработка проектирует API и модели;
- инженеры домена подтверждают, что система отражает реальность, а не только внутреннюю логику команды.
Проблема в том, что без такого языка каждая роль быстро начинает использовать свои локальные слова.
В кейсе лунной базы это может выглядеть так:
- аналитика говорит “ресурс”;
- логистика говорит “запас”;
- инженеры жизнеобеспечения говорят “резерв”;
- архитектура рисует
inventory service; - разработка делает
resourcestable; - эксплуатация называет всё это “критическими материалами”.
Формально все как будто говорят об одном. Практически — уже нет.
Ubiquitous language полезен именно тем, что заставляет сделать эти различия явными достаточно рано.
Минимальный рабочий метод для аналитика, как его собирать:
- Выписать термины из интервью и документов — буквально как их произносят люди.
- Отметить спорные — те, вокруг которых возникает «подождите, вы о чём».
- Найти слова с несколькими смыслами — один термин, за которым стоят разные понятия.
- Привязать термины к сценариям — где именно слово используется и что от него зависит.
- Согласовать glossary не глобально, а по контекстам — не «один словарь на всё», а свой согласованный язык внутри каждого контекста.
Последний пункт ключевой: попытка сделать единый словарь на всю систему обычно стирает именно те различия, ради которых язык и нужен.
Bounded context: не про коробки, а про границы смысла
Одно из самых полезных последствий DDD — понимание, что одна и та же сущность в разных частях системы может значить разное.
Не потому, что команда ошиблась, а потому, что система действительно состоит из разных смысловых областей.
Важный момент: bounded context — это не “будущий сервис” и не “ещё одна коробка на диаграмме”. Это прежде всего граница, внутри которой язык и модель остаются согласованными.
Когда команда начинает рисовать контексты как будущие сервисы слишком рано, DDD быстро вырождается в другой способ делать преждевременную декомпозицию. Гораздо полезнее сначала понять:
- где начинается разный смысл;
- где одинаковые термины начинают вести себя по-разному;
- где разные команды и процессы реально смотрят на домен под разными углами.
Только потом уже можно обсуждать, станут ли эти границы сервисами, модулями или просто отдельными частями общей модели.
Лунная база: какие контексты там естественны
В кейсе лунной базы довольно быстро можно увидеть несколько естественных контекстов. Это именно bounded contexts, а не просто разделы системы, по трём признакам: внутри каждого свой язык (одни и те же слова значат разное), свои правила (что допустимо и что критично) и свой владелец решений (кто отвечает за домен). Где меняется хотя бы одно из трёх — там и проходит граница смысла.
Жизнеобеспечение
Здесь важны:
- состояние воздуха, воды, давления, температуры;
- критичные пороги;
- деградационные режимы;
- приоритет безопасности над экономией.
Почему граница смысла: свой язык порогов и аварий, правило «безопасность важнее экономии», владелец — инженеры жизнеобеспечения.
Энергетика
Здесь другой язык:
- генерация;
- накопление;
- распределение;
- приоритеты потребителей;
- резервные режимы.
Почему граница смысла: язык баланса и приоритетов потребления, правила распределения мощности, владелец — энергетики; «резерв» здесь — мощность, а не запас.
Логистика и ресурсы
Здесь начинают жить:
- запасы;
- расход;
- пополнение;
- резервирование;
- критичность ресурса;
- планирование поставок и перераспределения.
Почему граница смысла: язык запасов и движения ресурсов, правила резервирования и пополнения, владелец — логистика; «резерв» здесь — складской буфер.
Робототехника и внешние операции
Тут уже важны:
- задания;
- маршруты;
- подтверждения;
- связь;
- локальная автономность;
- ограничения окружающей среды.
Почему граница смысла: язык заданий и маршрутов, правила подтверждения и автономного исполнения, владелец — операторы внешних операций.
Наземный контур планирования
А здесь появляется другой смысл:
- прогноз;
- долгий горизонт планирования;
- координация поставок;
- аналитика по всей базе;
- компромиссы между локальной автономией и глобальной оптимизацией.
Почему граница смысла: язык прогноза и долгого горизонта, правила глобальной оптимизации, владелец — наземное планирование; «состояние базы» здесь — сводный прогноз, а не текущие пороги.
Важно, что слово “состояние базы” внутри этих контекстов может означать разные вещи. И именно здесь bounded context начинает помогать, а не просто украшать разговор.
flowchart TD
A["Лунная база"] --> B["Жизнеобеспечение"]
A --> C["Энергетика"]
A --> D["Логистика ресурсов"]
A --> E["Робототехника"]
A --> F["Наземное планирование"]
B --> G["Безопасность и пороги"]
C --> H["Баланс и приоритеты"]
D --> I["Запасы, резервы, пополнение"]
E --> J["Задания, маршруты, подтверждения"]
F --> K["Прогноз, координация, аналитика"]
Контекстная карта: контексты обмениваются смыслом
Контексты не существуют изолированно — они отдают друг другу не «таблицы», а согласованные понятия. Даже без формальных DDD-паттернов полезно увидеть, что именно один контекст передаёт другому:
- логистика отдаёт «план поставок и пополнения»;
- жизнеобеспечение отдаёт «критичные резервы и пороги»;
- энергетика отдаёт «лимиты потребления»;
- наземное планирование собирает это в «прогноз и координацию по всей базе».
flowchart LR
L["Логистика"] -->|план поставок| P["Наземное планирование"]
J["Жизнеобеспечение"] -->|критичные резервы и пороги| P
E["Энергетика"] -->|лимиты потребления| P
P -->|прогноз и приоритеты| L
Важная деталь: на границе контекстов один и тот же объект переводится, а не просто копируется. «Резерв» логистики, попадая в наземное планирование, превращается во вход (показатель) прогноза, а не остаётся складским буфером. Где этот перевод не сделан явно — там и рождаются самые дорогие рассогласования.
Где аналитика помогает DDD, а где может его испортить
Аналитика очень полезна для DDD, когда:
- рано фиксирует различия в языке;
- помогает отделять похожие, но не тождественные понятия;
- не пытается свести разные контексты к “единому универсальному словарю”;
- удерживает связь между процессами, требованиями и моделью;
- приносит в обсуждение реальный эксплуатационный смысл терминов.
Но аналитика же легко может DDD и испортить, если:
- стремится слишком быстро сделать “единую нормализованную модель на всё”;
- считает разницу в терминах чисто редакционной проблемой;
- выравнивает язык так, что из него исчезают реальные смысловые различия;
- смешивает пожелание к удобству документации с реальной структурой домена.
Хорошая аналитика здесь не упрощает домен искусственно, а делает его различия видимыми и управляемыми.
Короткий checklist перед разметкой доменной модели
Перед тем как рисовать bounded contexts или спорить о модели, полезно проверить:
- Какие термины команда использует одинаково, но подразумевает под ними разное?
- Где один и тот же объект живёт в разных процессах с разным смыслом?
- Какие различия в языке реально влияют на требования и архитектуру?
- Где команда пытается создать “единый словарь” ценой потери важных доменных различий?
- Какие контексты действительно естественны для системы, а какие пока появились только из удобства текущей оргструктуры?
- Какие части модели особенно важны для автономности, безопасности и деградации?
- Какие понятия пересекают границы контекстов и требуют явного перевода?
- Что в доменной модели уже сейчас должен подтвердить инженер домена, а не только аналитик или разработчик?
Если эти вопросы не пройдены, то дальше очень легко получить красивую схему с неверной картиной реальности.
Что дальше
Мы разобрали, как доменная модель удерживает важные различия. Дальше посмотрим, что происходит, когда модель выбрана неверно: как доменная модель ломает и спасает архитектуру — про то, как ошибка в модели расходится по API, данным и границам системы, и как правильная модель, наоборот, спасает архитектуру.
Комментарии