Влад Хононов

Что такое предметно-ориентированное проектирование?


(What is Domain-Driven Design?)

Глава 3
Управление сложностью при помощи ограниченного контекста
Как вы узнали из предыдущей главы, чтобы обеспечить успех проекта, важно разработать единый язык — ясный, последовательный и отражающий ментальные модели экспертов предметной области.

Однако эти модели могут быть несогласованными, что противоречит ключевому требованию единого языка. Давайте рассмотрим пример.
Пример: несогласованные модели
Предположим, что мы работаем на телемаркетинговую компанию. Отдел маркетинга компании генерирует лидов (потенциальных клиентов) через онлайн-рекламу. Отдел продаж занимается обращением к лидам с предложением купить продукты или услуги компании, как это показано на Рисунке 3-1.

Рисунок 3-1. Пример предметной области — телемаркетинговая компания

Изучение языка экспертов предметной области приводит к интересному наблюдению. Термин «лид» в отделе маркетинга и отделе продаж имеет разные значения:

Отдел маркетинга
Для маркетологов лид представляет собой уведомление о том, что кто-то заинтересован в одном из продуктов. Событие получения контактных данных потенциального клиента считается лидом.

Отдел продаж
В контексте отдела продаж лид представляет собой намного более сложную сущность. Он подразумевает весь жизненный цикл процесса продаж. Это не просто событие, а долгий процесс.

Как сформулировать единый язык для этой телемаркетинговой компании?
С одной стороны, мы знаем, что единый язык должен быть согласованным — каждый термин должен иметь одно значение. С другой стороны, мы знаем, что этот язык должен отражать ментальные модели экспертов предметной области. В этом случае ментальная модель «лид» не согласована между экспертами предметной области в отделах продаж и маркетинга.

Эта неоднозначность не является большой проблемой в коммуникациях между людьми. Конечно, коммуникация между людьми из разных отделов может быть сложной, но для людей достаточно просто определить точное значение в контексте взаимодействия.

Однако в программировании представить такую противоречивую модель предметной области гораздо сложнее. Исходный код плохо справляется с неоднозначностью. Если бы мы попытались внедрить многоступенчатую модель отдела продаж в маркетинг, это привело бы к ненужной сложности. А если бы мы попытались упростить модель продаж согласно точке зрения маркетинга, она не соответствовала бы потребностям предметной подобласти продаж. В первом случае мы получили бы излишне сложное решение, а во втором — недостаточно сложное.
Как решить этот парадокс?

Один из вариантов — добавить к проблемному термину префикс с определением контекста: «маркетинговый лид» и «лид продаж». Это позволило бы избежать проблем с реализацией модели в коде. Однако в разговорах никто не использует префиксы. Людям не нужна дополнительная информация — они могут полагаться на контекст беседы.

Обратимся к шаблону из методологии предметно-ориентированного проектирования для решения таких сценариев — «ограниченному контексту» (bounded context).
Что такое ограниченный контекст?
Решение тривиальное: разделить единый язык на несколько языков поменьше, а затем каждый из них привязать к явному контексту, в котором он может быть применен — его ограниченному контексту.

В предыдущем примере мы можем выделить два ограниченных контекста: маркетинг и продажи. Термин «лид» существует в двух ограниченных контекстах, как показано на Рисунке 3-2. Пока он принимает одно значение в каждом из ограниченных контекстов, каждый из четко разделенных единых языков является согласованным и при этом отражает ментальные модели экспертов предметной области.

Рисунок 3-2. Устранение несогласованности в едином языке путем разделения его на ограниченные контексты

В каком-то смысле конфликты терминологии и неявные контексты являются неотъемлемой частью любого крупного бизнеса. С использованием паттерна ограниченного контекста, они моделируются как явная и неотъемлемая часть предметной области.
Границы модели
Как мы обсудили в предыдущей главе, модель — это не копия реального мира, а конструкция, которая помогает понять сложную систему. Проблема, которую она должна решить, является неотъемлемой частью модели — её назначением. Модель не может существовать без ограничений, иначе она будет расширяться, становясь копией реального мира. Это делает ограниченные контексты неотъемлемой частью процесса моделирования.

Вернемся к примеру с картами в качестве моделей. Мы видели, что каждая карта имеет свой специфический контекст — воздушный, навигационный, территориальный, метро и т. д. Карта полезна и согласована только в рамках её конкретной цели.

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

Термины языка согласованы только внутри его ограниченного контекста.
Объём ограниченного контекста
Пример в начале главы продемонстрировал внутреннюю границу предметной области. Эксперты из разных отделов имели противоречивые представления о модели одной и той же сущности. Для моделирования предметной области нам пришлось разделить модель и определить строгий контекст применимости для каждой из тонко разграниченных моделей — её ограниченный контекст.

Согласованность единого языка помогает определить его самую широкую границу. Она не может быть ещё шире: это может привести к возникновению несогласованных моделей и терминологии. Однако мы всё равно можем декомпозировать модели дальше, на ещё более мелкие ограниченные контексты, как показано на Рисунке 3-3.

Рисунок 3-3. Ограниченные контексты

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

Размер ограниченного контекста сам по себе не является определяющим фактором. Моделям не обязательно быть большими или маленькими. Им нужно быть понятными. Чем шире граница единого языка, тем сложнее поддерживать его согласованность. Может быть полезно разделить большой единый язык на более мелкие, более управляемые области задач. С другой стороны стремление к маленьким ограниченным контекстам также может иметь негативные последствия: чем они меньше, тем большие расходы потребуются на их интеграцию.

Таким образом, решение о том, насколько большими должны быть ваши ограниченные контексты, зависит от конкретной области задач. Иногда широкие границы будут более понятны, а иногда лучше подойдет декомпозиция. Мы обсудим факторы, которые влияют на это решение, далее в Главе 9.
Ограниченные контексты против предметных подобластей
В Главе 2 мы видели, что предметная область состоит из нескольких предметных подобластей. В этой главе мы рассмотрели декомпозицию предметной области на набор тонко разграниченных областей задач или ограниченных контекстов. На первый взгляд, существование двух методов декомпозиции предметных областей может показаться излишним. Однако это не так. Давайте разберемся, почему.
Предметные подобласти
Чтобы понять бизнес компании, мы должны проанализировать её предметную область. Согласно методологии предметно-ориентированного проектирования, фаза анализа включает обнаружение (identification) различных типов предметных подобластей (основных, поддерживающих и общих). Ключевое слово здесь — «обнаружение». Предметные подобласти уже существуют; они являются частью бизнеса. Это то, как работает организация и как она планирует свою конкурентную стратегию. Анализируя предметную область, мы обнаруживаем существующие подобласти.
Ограниченные контексты
Ограниченные контексты, с другой стороны, — разрабатываются (designed). Выбор границ моделей — ограниченных контекстов — это стратегическое проектное решение. Именно мы решаем, как разделить бизнес-область на более мелкие, управляемые области задач.
Взаимодействие между предметными подобластями и ограниченными контекстами
Хотя практически это нецелесообразно, но одна модель теоретически может охватывать всю предметную область. Эта стратегия может сработать для небольшой системы, как показано на Рисунке 3-4.

Рисунок 3-4. Неделимый ограниченный контекст

При необходимости мы можем разбить модель на ограниченные контексты, в соответствии с ментальными моделями экспертов предметной области, как показано на Рисунке 3-5.

Рисунок 3-5. Ограниченные контексты, обусловленные согласованностью единого языка

Если модели всё равно остаются большими и сложными в обслуживании, мы можем декомпозировать их на ещё более мелкие ограниченные контексты; например, иметь ограниченный контекст для каждой предметной подобласти, как показано на Рисунке 3-6.

Рисунок 3-6. Ограниченные контексты, согласованные с границами предметных подобластей

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

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

Важно помнить, что предметные подобласти обнаруживаются (discovered), в то время как ограниченные контексты разрабатываются (designer). Следует адаптировать разработку решения в соответствии с конкретным потребностям проекта.
Физические границы
Ограниченные контексты служат не только границами модели, но и физическими границами систем, реализующих их. Каждый ограниченный контекст должен быть реализован в отдельном решении: он реализуется, развивается и обновляется независимо от других ограниченных контекстов.

Четкие физические границы между ограниченными контекстами позволяют нам реализовывать каждый ограниченный контекст с набором технологий, которые лучше всего подходят для его потребностей.
Границы владения
Исследования показывают, что чем крепче забор, тем лучше соседи. В случае программных проектов мы можем использовать границы модели — ограниченные контексты — для мирного сосуществования команд. Разделение работы между командами — это ещё одно стратегически важное решение, которое можно принять, используя паттерн ограниченного контекста.

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

Важно отметить, что отношения между командой и ограниченным контекстом однонаправленные: ограниченный контекст должен принадлежать только одной команде. Тем не менее, одна команда может владеть несколькими ограниченными контекстами.

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

С появлением новой предметной подобласти, создаются новые ограниченные контексты. Разделение предметной области на ограниченные контексты — это стратегически важное решение в проектировании.

Ограниченный контекст и его единый язык могут быть реализованы и поддерживаться только одной командой. Две разных команды не могут по отдельности разрабатывать один ограниченный контекст. Тем не менее, одна команда может работать одновременно над несколькими ограниченными контекстами.
Глава 4
Сопоставление контекстов