Влад Хононов

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


(What is Domain-Driven Design?)

Глава 9. Эволюционное проектирование
Ни одна современная компания не может позволить себе снижение темпов развития. Чтобы не отставать от конкурентов, компаниям приходится постоянно меняться, эволюционировать и даже переосмысливать себя со временем. Мы не можем игнорировать этот факт при проектировании систем, особенно если мы намерены создать программное обеспечение, хорошо адаптированное к своей предметной области.

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

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

Изменения в предметных подобластях

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

Основные
Вещи, которые компания делает отлично от других и которые обеспечивают ей конкурентное преимущество

Поддерживающие
Вещи, которые компания делает отлично от конкурентов, но преимущества они не дают

Обобщённые
Вещи, которые все компании делают одинаково

Не редкость, когда некоторые из предметных подобластей компании меняются свой тип в процессе существования. Давайте рассмотрим несколько примеров таких изменений.
От основной к обобщённой
Предположим, что интернет-ритейлинговая компания, скажем, «Азамон», разрабатывала собственное решение по доставке заказов. Она придумала гениальный алгоритм для оптимизации маршрутов своих курьеров и таким образом смогла установить цену за доставку ниже, чем у конкурентов.

Однако вскоре компания «Уреб» радикально повлияла на индустрию доставки. Она заявила, что решила задачу коммивояжера (разъездной посредник) и начала предоставлять услуги оптимизации маршрута. Оптимизация Уреб оказалась не только более продвинутой, но и стоила существенно дешевле.

С точки зрения Азамона, как только решение Юреба стало доступным как готовый продукт, его основная предметная подобласть превратилась в обобщённую. Оптимальное решение стало доступным для всех конкурентов Азамона и он больше не владел конкурентным преимуществом.
От обобщённой к основной
Типичным примером компании, превращающей обобщённую предметную подобласть в основную, является Amazon. Им, как и всем поставщикам услуг, требовалась инфраструктура для запуска своих сервисов. Компания смогла заново изобрести способ управления своей физической инфраструктурой, а позже даже превратила его в прибыльный бизнес: Amazon Web Services.
От поддерживающей к основной
Поддерживающая предметная подобласть также может превратиться в основную — например, если компания найдёт способ оптимизировать поддерживающую логику таким образом, чтобы она либо снижала затраты, либо приносила дополнительную прибыль.

Типичным симптомом такой трансформации является увеличение сложности бизнес-логики поддерживающей предметной подобласти. Поддерживающие подобласти по определению просты и в большей степени напоминают интерфейсы CRUD или процессы ETL. Однако если со временем бизнес-логика становится более сложной, у этого должна быть причина. Если это не влияет на прибыль компании, почему она стала более сложной? Если это действительно увеличивает прибыль компании, это признак того, что поддерживающая предметная подобласть превращается в основную.
Проблемы тактического проектирования
Другим симптомом изменения типа предметной подобласти является неспособность существующего технического проектирования поддерживать текущие бизнес-потребности.

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

Если со временем в бизнес-логику добавляются сложные правила и инварианты, кодовая база также становится сложнее. Добавление новой функциональности будет болезненным, так как проектирование не будет поддерживать новый уровень сложности. Эта «боль» является важным сигналом. Используйте ее как триггер необходимости переоценки области и смены решений проектирования.
Эволюция тактического проектирования
Не стоит бояться необходимости изменения стратегии реализации. Это нормально. Мы не можем предвидеть, как будет развиваться бизнес. Мы также не можем применять самые сложные шаблоны проектирования для всех типов предметных подобластей — это было бы затратно и неэффективно. Нужно выбирать наиболее подходящий способ проектирования и улучшать его, когда это необходимо.

Если решение о том, как моделировать бизнес-логику, принимается сознательно и вы осведомлены о всех возможных вариантах проектирования и различиях между ними, переход от одного паттерна проектирования к другому не так уж и сложен. Вот несколько примеров:

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

От активной записи к модели предметной области
Начните с определения объектов-значений. Какие структуры данных можно моделировать как неизменяемые объекты? Найдите связанную с ними бизнес-логику и сделайте её частью объектов-значений.

Затем проанализируйте структуры данных и определите границы транзакций. Какие иерархии нужны, чтобы обеспечить строгое согласование проверки бизнес-правил и инвариантов? Так появятся возможности создания агрегатов. Наконец, для каждого агрегата определите его корень — точку входа для его общедоступного интерфейса.

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

Тривиальным примером такого изменения является расширение центров разработки. Чтобы адаптироваться к развивающимся бизнес-потребностям, центры разработки растут и часто разделяются на удаленные друг от друга офисы. Давайте посмотрим, как это может повлиять на эволюцию паттернов интеграции:

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

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

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

От паттерна раздельных путей к паттернам партнёрства или заказчик-поставщик
Как вы видели ранее, команды могут идти раздельными путями в случаях работы с поддерживающими и обобщёнными предметными подобластями (с точки зрения бизнеса нет смысла в дублировании функциональности основной предметной подобласти). Ранее в этой главе вы также видели, как и поддерживающая, и обобщённая предметные подобласти могут превратиться в основную. Если функциональность эволюционировавшей предметной подобласти была продублирована несколькими командами, им придется интегрировать свои реализации. В этом случае лучше подойдет паттерн заказчик-поставщик, так как тогда основная предметная подобласть будет реализована только одной командой.
Знание о предметной области
Фундаментальный принцип предметно-ориентированного проектирования гласит, что знания о предметной области — это важнейший элемент проектирования. Приобретение знаний о предметной области — один из наиболее сложных аспектов программной инженерии, особенно для основных предметных подобластей, где логика не только сложна, но и подвержена частым изменениям.

Неточность знаний о предметной области несет в себе риски, особенно для стратегического проектирования. Цена ошибки при декомпозиции системы на ограниченные контексты может быть высока.

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

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

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