Привет, Хабр!
На протяжении нескольких лет одной из наиболее популярных и важных книг в нашем арсенале остаётся книга Влада Хононова «Изучаем DDD предметно-ориентированное проектирование«. Мы регулярно контактируем с Владом и надеемся, что вскоре сможем опубликовать здесь и развёрнутое интервью с ним. А сегодня хотим предложить вам подробный и несколько критический обзор его книги, найденный в одном англоязычном блоге. Автор статьи не скрывает, что книга Влада не вполне подошла под конкретные задачи, которые автор надеялся с её помощью решить и упростить. Но при этом он настолько толково описывает саму парадигму, а также как именно и для каких целей её лучше использовать, что мы сочли её отличной и честной рекламой нашего бестселлера. Далее — авторский обзор от сеньора Факундо Оланы из Аргентины
Контекст
Я начинал карьеру программиста в стезе Java. В те времена из каждого утюга рассказывали о приложениях для больших предприятий. Приходилось пользоваться Java Enterprise Edition и далее применять паттерны Enterprise-архитектуры, реализуемые через Enterprise Java Beans. Мне было непонятно, по каким показателям одни приложения можно считать более соответствующими энтерпрайзу, чем другие, или почему, придерживаясь определённого набора ритуалов получаются адекватные решения, а без них — не получаются. Мне казалось подозрительным, что эти концепции программирования как будто существуют только внутри пузыря экосистемы Java.
Вскоре я покинул эту компанию, где писали на Java, и вообще отошёл от программирования на Java, после чего слово «энтерпрайз» отошло в моём сознании на второй план как какой-то малоупотребительный термин, к которому неравнодушны фанаты «Стар Трек». Далее я работал над потребительскими веб-приложениями, затем в одном СМИ, далее в онлайн-сообществе по игре «MTG», в SaaS-провайдере, в технологической рекламной компании, потом в стартапе по крипте, потом в стартапе по ИИ (наверное, отчасти это объясняет, почему мне понадобилось сделать перерыв ы карьере).
В прошлом году я перешёл на, можно сказать, менее претенциозную и более скучную с технологической точки зрения работу в сфере здравоохранения. Инженерные вызовы, возникающие в этой новой компании, связаны не с масштабом, или ростом, или изощрённым инструментарием, а со сложностью предметной области. Здесь необходимо проектировать с учётом сферы, в которой работает организация, именно этим определяется программная архитектура, при помощи которой автоматизируют и, в конечном счёте, упрощают бизнес-процессы. Заметив такой сдвиг акцентов, я решил вновь обратиться к основам, поэтому читал и сам писал о наработке знаний и проектировании через тестирование. Во втором посте, упомянутом в предыдущем предложении, я затрагиваю книгу о модульном тестировании. В конце концов, я понял, что могу сформулировать, что такое энтерпрайз-приложение:
Энтерпрайз-приложение нацелено на автоматизацию внутренних процессов организации или должно способствовать такой автоматизации. Такая автоматизация может существовать во многих формах, но обычно энтерпрайз-приложения обладают следующими свойствами:
-
Высокая сложность бизнес-логики
-
Длительный жизненный цикл проекта
-
Умеренные объёмы данных
-
Низкие или умеренные требования к производительности
Эти пункты весьма точно описывают область, в которой мне сейчас приходится работать, и нехарактерны для тех областей, в которых я работал ранее. Поясню, с какими вызовами я сейчас сталкиваюсь: приходится разбирать по полочкам бизнес-процессы, согласовывать терминологию, модернизировать унаследованный монолит, выяснять, какие объекты существуют в предметной области, и кто должен ими владеть. Естественно, в такой ситуации мне потребовалось освежить знания о предметно-ориентированном проектировании (DDD).
Тогда я приобрёл книгу Влада Хононова «Изучаем DDD – предметно-ориентированное проектирование», так как считаю её современной альтернативой классической синей книге Эрика Эванса. В ней обобщены и обновлены те же самые идеи, что и у Эванса, которые дополнительно соотнесены с такими более новыми технологиями, как микросервисы, событийно-ориентированная архитектура и Data Mesh.
Что в книге
В первой части «Стратегическое проектирование» рассматриваются концепции DDD, мне она была наиболее полезна. В оставшейся части этого раздела моей статьи я подробнее расскажу, что описано в этой части.
-
Предметная область — это основная сфера деятельности компании, с которой связаны те услуги, которые компания оказывает своим клиентам. Компания может действовать в нескольких предметных областях, и набор этих областей со временем может меняться.
-
Поддомен — это конкретизированная область бизнес‑деятельности. Из всех поддоменов компании образуется предметная область, в которой компания ведёт бизнес. С технологической точки зрения поддомены напоминают наборы взаимосвязанных взаимно согласованных практических юзкейсов. Как правило, все юзкейсы реализуются одними и теми же акторами и бизнес‑объектами, и все они оперируют сильно взаимосвязанными данными.
-
Существует три типа поддоменов:
-
Основной поддомен — это аспекты, в которых компания отличается от своих конкурентов. Например, изобретает новые товары или услуги или сокращает затраты, оптимизируя уже существующие процессы. Основные поддомены по определению сложны.
-
Универсальный поддомен — это та часть бизнеса, которой все занятые в этом бизнесе компании реализуют более‑менее одинаково. Обычно такие поддомены сложно как концептуализировать, так и внедрить, но для проблем из этого поддомена широко известны проверенные на практике решения.
-
Вспомогательный поддомен — это деятельность, важная для достижения бизнес‑целей компании, но не обеспечивающая компании конкурентного преимущества. Бизнес‑логика во вспомогательных поддоменах отличается невысокой сложностью, поэтому такие поддомены можно дёшево реализовать собственными силами.
-
|
Тип поддомена |
Конкурентное преимущество |
Сложность |
Гибкость |
Реализация |
Задача |
|
Основной |
Да |
Высокая |
Высокая |
Собственными силами |
Интересная |
|
Универсальный |
Нет |
Высокая |
Низкая |
Купить или заимствовать |
Решённая |
|
Вспомогательный |
Нет |
Низкая |
Низкая |
Собственными силами или через аутсорсинг |
Очевидная |
-
Эксперты в предметной области — это авторитетные знающие специалисты, отвечающие за предметную область при разработке ПО. Это либо те, кто формулируют функциональные требования к ПО, либо конечные пользователи продукта. Именно их задачи призван решать создаваемый софт.
-
Задача аналитиков и инженеров — преобразовать представления эксперта в требования к ПО и исходный код.
-
Успех программного проекта зависит от того, насколько эффективно обмениваются знаниями эксперты‑предметники и инженеры‑программисты.
-
-
Единый язык — это терминология, описывающая предметную область. На едином языке общаются все заинтересованные лица, занятые в проекте. Благодаря единому языку, эксперты‑предметники и члены команды разработчиков могут общаться без дополнительной помощи переводчиков и других посредников.
-
Единый язык должен состоять из терминологии, относящейся к предметной области, а не из технического жаргона.
-
Он должен быть самосогласованным, не содержать синонимичных или неоднозначных терминов.
-
Он подлежит постоянной проверке и должен развиваться.
-
Составлением единого языка должны совместно заниматься эксперты‑предметники и представители команды разработчиков. (Существовавший ранее бизнес‑язык, привычный экспертам, может оказаться неэффективен при моделировании предметной области).
-
-
Поскольку разные эксперты‑предметники могут не сходиться во мнениях по поводу бизнеса, единый язык делится на более мелкие самосогласованные языки, у каждого из которых есть более конкретная область применения. Такая область называется «ограниченный контекст».
-
Одно из стратегических решений, принимаемых при проектировании — это определить область применения единого языка, то есть, его ограниченные контексты. Чем больше граница, тем сложнее поддерживать самосогласованность контекста. Напротив, чем она меньше, тем больше издержек на интеграцию привносится в систему, спроектированную таким образом.
-
Каждый ограниченный контекст должен быть реализован как отдельный сервис/проект.
-
Каждым ограниченным контекстом должна владеть отдельная команда.
-
-
При этом, ограниченный контекст отличается от поддомена, хотя, оба они предполагают, что предметную область нужно декомпозировать. Вот чем отличаются эти понятия:
-
Поддомены выявляются в процессе анализа предметной области. В сущности, поддомены — это множество юзкейсов, которые удалось обнаружить.
-
Ограниченные контексты проектируются так, чтобы моделировать бизнес как совокупность мелких и удоброваримых областей применения задач.
-
-
В ограниченных контекстах выражаются разные и, возможно, взаимно противоречивые представления о предметной области, но эти контексты всё равно должны взаимодействовать друг с другом, чтобы из них складывались полезные системы. Есть несколько способов их интегрировать:
-
Ситуативное партнёрство, при котором команды, владеющие контекстами, координируют вносимые изменения.
-
Общее ядро, где подмножество двух ограниченных контекстов совместно используется участвующими командами и поддерживается в согласованном виде.
-
Конформистская интеграция, при которой контекст, предложенный потребителем, наследует модель от поставщика.
-
Предохранительный слой, где контекст потребителя подстраивается под модель поставщика через отдельный слой трансляции, чтобы таким образом защититься от восходящих изменений.
-
Сервис с открытым протоколом, где вышележащий ограниченный контекст предоставляет публичный интерфейс, чтобы защитить своих потребителей от внутренних деталей.
-
Следование разными путями, когда проще обойтись без координации, даже, если придётся выполнять двойную работу.
-
Комментарии
-
Считаю, что выделение основных, универсальных и вспомогательных поддоменов помогает вырабатывать эвристику для принятия решений — то есть, определять, во что стоит вкладываться. Это похоже на технику токенов инноваций. Так, если вы вкладываетесь в разработку сложного софта, не относящегося к вашему основному поддомену, то, вероятно, что‑то делаете неправильно. А если вы не знаете, какой поддомен у вас является основным, то всё совсем плохо!
-
Я категорически согласен с тем, что нужен единый язык. Если приходится останавливаться и размышлять, как именно лучше донести конкретную концепцию до определённой аудитории, то при принятии решений о проектировании возникает недопустимо много пробуксовок. Представьте себе ежедневную коммуникацию, при которой у вас отсутствует кратковременная память. Не сформулировав язык, невозможно накапливать знания, а не обзаведясь знаниями, вы не сможете написать софт.
-
Попытка продавить универсальную модель предметной области повсюду в большой организации — идея настолько же нежизнеспособная, как и эсперанто. Пусть создать такую универсальную модель и возможно, перейти непосредственно к ней не получится — точно как не получится сразу переписать большой софтверный проект. Лучше задать вектор, работать итерация за итерацией, пересчитывать, представляя при этом, что для нас будет «достаточно хорошо», и на каком этапе лучше остановиться, смирившись с некоторым несовершенством. Эти задачи очень удобно решать при помощи ограниченного контекста, поскольку он позволяет примирить конфликтующие представления о предметной области, скомпенсировать взаимное несовершенство, а значит — создать полезный и внутренне самосогласованный софт, который будет удобно поддерживать.
-
Считаю, что наилучшие результаты зависят не только от совместной разработки общего языка, но и от налаживания циклов обратной связи между экспертами‑предметниками и разработчиками ПО. Проектировщики ПО должны постоянно впитывать знания о предметной области от представителей бизнеса, но и в идеале сами катализировать изменения. Нужно не только моделировать процессы предметной области и усваивать правила бизнеса, но и изыскивать возможности, чтобы их упростить.
-
Предметно‑ориентированное проектирование подобно гибким методологиям в том, что опирается на тесный контакт между разработчиками ПО и пользователями — в данном случае, экспертами в предметной области. Наладить такой контакт бывает очень непросто, так как большинство организаций не приспособлено к такой коллаборации:
-
У экспертов‑предметников может не быть особого стимула участвовать в разработке ПО, усваивать новую терминологию или менять существующие бизнес‑процессы. В свою очередь, инженеры зачастую не хотят или не готовы общаться на нетехническом языке. В свою очередь, у представителей бизнеса зачастую не хватает терпения и времени, чтобы работать с инженерами.
-
Часто им приходится работать через посредников — владельцев продукта и аналитиков ПО, которые принимают на себя роль буфера или переводчика, осложняя при этом передачу знаний.
-
-
В книге автор признаёт некоторые из этих проблем, но не предлагает внятных решений — вероятно, потому, что они в большей степени относятся к управлению организацией и внутренней корпоративной политике, чем к разработке ПО. Я могу представить два варианта эффективного использования DDD в реальных организациях, где мне приходилось работать:
-
Руководство компании уже настроено внедрять DDD и может проинструктировать экспертов‑предметников, как тем работать с проектировщиками ПО.
-
Проектировщики ПО действуют самостоятельно и нуждаются в том, что в этой книге называется «законспирированным DDD». В данном случае сам софт может послужить инструментом, позволяющим двигаться в сторону DDD. Например, разработчики ПО могут стремиться к взаимной согласованности языка в создаваемых ими системах. Действительно, если софт даёт ощутимые преимущества, то у экспертов будет стимул переходить на него, а там и новая терминология приживётся. Разумеется, при этом есть риск, что проектировщики изобретут неправильную терминологию из‑за того, что недостаточно хорошо разбираются в предметной области.
-
-
Меня не слишком заинтересовала вторая часть книги, посвящённая тактическому замыслу. На мой взгляд, она слишком много предписывает и разбита на паттерны, возможно, из уважения к классической формулировке DDD, которая исходно ассоциировалась с конкретными приёмами программирования и архитектурными паттернами для больших предприятий. В основе нескольких этих глав лежит дерево эвристических решений, где тип поддомена и несколько других атрибутов каскадируют в конкретное решение, принимаемое при проектировании и в процессе разработки (моделирование данных, архитектура приложения, стратегия тестирования):

В книге подчёркивается, что эта эвристика дана для справки и не должна пониматься как железные правила. То есть, пока проектирование идёт в русле предметной области, вы всё делаете правильно. При этом автор уделяет больше внимания деталям реализации, а не тем принципам, на которых они основаны. В частности, одна из глав книги посвящена альтернативным паттернам моделирования данных. В ней рассматриваются транзакционный сценарий (Transaction Script), активная запись (Active Record), модель предметной области (Domain Model) и модель предметной области, основанная на событиях (Event‑Sourced Domain Model). Сомневаюсь, что можно многого добиться, смешивая и сочетая эти паттерны в зависимости от сложности поддомена. Меня более интересуют принципы, лежащие в их основе, такие, при помощи которых можно адаптировать любой инструмент к конкретному проекту, так, чтобы в дальнейшем этот проект развивался в предметно‑ориентированном ключе.
Далее, на мой взгляд, книга обретает прежнюю увлекательность ближе к концу части III, где рассказано, как развивать решения, а также как внедрять DDD в уже существующие проекты. Характерно, что о реальной применимости таких методов рассказано только на нескольких страницах в главе 13. Любой бизнес, сложность которого оправдывает создание предметно‑ориентированного софта (то есть, любых приложений для большого предприятия) непременно обрастает настоящими джунглями переусложнённого унаследованного кода. Поэтому давно существующие проекты должны изучаться как норма, а не как исключение.
Меня приятно удивило, насколько ценными оказались несколько последних глав, в которых автор рассказывает, как интегрировать подход DDD с другими методологиями. В частности, в этой главе я нашёл одну из лучших трактовок микросервисов, какие мне только попадались. Здесь микросервисы рассмотрены не только в контексте DDD, но и в рамках модульного проектирования, в духе работ Джона Аустерхаута и Гленфорда Дж. Майерса. Благодаря ним была сформулирована следующая мудрость:
Тема сложности далеко не ограничивается попытками всего лишь минимизировать сложность отдельных локальных участков программы. Гораздо важнее заниматься глобальной сложностью, то есть, сложностью общей структуры программы или системы (т.e., насколько связаны или взаимозависимы основные элементы программы).
Заключение
Книга «Изучаем DDD — предметно-ориентированное проектирование» хороша, если вам требуется освежить в памяти ключевые концепции этой методологии или познакомиться с некоторыми малоизвестными приёмами, о которых я только что-то слышал. Притом, что я ожидал от этой книги большего в том, что касается применимости её материала в моей повседневной работе, последние несколько глав убедили меня, что автор знает своё дело. Кстати, не так давно он опубликовал более фундаментальную книгу о проектировании ПО, с которой я определённо собираюсь познакомиться.
ссылка на оригинал статьи https://habr.com/ru/articles/1027422/