Subdomain и Bounded Context: как не перепутать границы

Одинаковые названия модулей еще не означают, что бизнес и система разделены одинаково.
В интернет-магазине есть модули Product, Order и Customer. Все выглядит понятно, пока команда не меняет цену товара. Каталог хранит базовую цену, продажи применяют скидку, склад учитывает закупочную стоимость. Путаница между Subdomain и Bounded Context собирает эти смыслы в одну модель, и правка задевает чужие правила.
Различие простое: Subdomain описывает часть бизнеса, а Bounded Context задает границу программной модели. На примере магазина разберем, как найти субдомены, спроектировать контексты и выбрать границу для постепенной правки легаси.

Сначала раздели бизнес, а не код

Домен в Domain-Driven Design: предметная область, для которой создают систему. В нашем примере это розничная торговля через интернет. Субдомен отвечает за отдельную бизнес-возможность внутри нее.
Магазину нужно управлять ассортиментом, продавать товары и выполнять заказы. Эти задачи существуют независимо от того, собрана система в одном приложении или в десятке сервисов. Получаются три кандидата в субдомены:
Дерево пакетов или список сервисов здесь не помогут: они показывают уже принятое техническое решение вместе со старыми ошибками. Ищи границы в целях бизнеса. Каталог дает покупателю актуальный ассортимент, продажи превращают намерение купить в заказ, а выполнение передает оплаченный товар получателю. Разные цели и причины изменений указывают на разные субдомены.
Проверь процессы и язык. «Товар» в каталоге означает опубликованное описание позиции. Для склада это физический остаток с местом хранения и доступным количеством. «Цена» в каталоге служит базовым значением, а в продажах становится результатом расчета с учетом скидок.
Одного различия в словах мало. Поговори с экспертами и сопоставь реальные правила. Граница становится убедительной, когда расходятся цель, терминология, процесс или причины изменений.

Subdomain и Bounded Context решают разные задачи

После разбора бизнеса команда проектирует программную модель. Bounded Context, или ограниченный контекст, задает область, внутри которой термины и правила имеют согласованный смысл.
В контексте каталога Product хранит название, описание и характеристики опубликованной позиции. В продажах похожая модель проверяет предложение и рассчитывает итоговую стоимость. Обе модели могут ссылаться на один идентификатор товара, но общая сущность со всеми полями им не нужна.
Так команда продаж меняет расчет скидки, не втягивая каталог в каждую акцию. Каталог расширяет характеристики товара, а оформление заказа ничего не узнает о размере изображения или порядке блоков карточки.
ВопросSubdomainBounded Context
Что описываетБизнес-возможностьОбласть применимости модели
Где находитсяВ пространстве проблемыВ пространстве решения
Как появляетсяКоманда обнаруживает его через цели, правила и язык бизнесаКоманда проектирует его с учетом системы и организации
Главная проверкаЕсть ли самостоятельная цель и набор правилОднозначны ли термины и правила внутри границы
Рабочая формула: субдомены обнаруживают, bounded contexts проектируют. Понимание бизнеса со временем уточняется, однако переименование модуля или разделение сервиса само по себе бизнес не меняет.

Соответствие один к одному удобно, но не обязательно

Для начала каждому субдомену можно дать свой Bounded Context. Каталог получает модель каталога, продажи модель предложения и заказа, выполнение модель резерва и отправления. Такие границы проще обсуждать, а изменения реже затрагивают чужую ответственность.
В реальной системе встречаются другие варианты:
Смотри на последствия. Если изменение скидок требует релиза каталога, общая модель смешивает причины изменений. Если два сервиса всегда меняются и выпускаются вместе, разделение, вероятно, формально. Перевод термина на стыке допустим, когда он явный и каждая сторона сохраняет свой смысл.

Как менять границы в легаси

В монолите Product часто хранит цену, остаток, правила публикации, скидки и данные поставщика. Это говорит лишь о том, что несколько смыслов попали в одну техническую границу.
Переписывать систему целиком опасно: новая реализация может повторить прежнюю структуру. Начни с конкретного пересечения. Каталог публикует базовую цену, продажи рассчитывают цену предложения, склад использует закупочную стоимость. Зафиксируй определения и перестань читать базовую цену при расчете заказа, передавая в продажи отдельное предложение.
Границу пора менять, если:
Выбери частый сценарий или ошибку с заметной ценой, уточни язык и назначь владельца правил. Иногда достаточно интерфейса и слоя перевода внутри монолита. Вынос в сервис оправдан позже, если независимый релиз, масштабирование или владение команды окупят интеграционную сложность.
Стабильный административный модуль с простыми правилами может обслуживать несколько второстепенных субдоменов. Если общая граница не тормозит изменения и не искажает язык, миграция ради симметрии не нужна.

Чеклист для обсуждения границ

Если ответы начинаются с таблиц, классов и API, вернись к целям бизнеса, процессам и языку экспертов. Так различие между Subdomain и Bounded Context станет основанием для решения: проведи границы моделей заново и выбери одно дорогое пересечение для ближайшего изменения.