Здравствуйте, хабрапользователи! В этой статье речь пойдет о предметно-ориентированном проектировании программного обеспечения с использованием, в первую очередь, стратегических шаблонов. Вторую часть – про тактическое проектирование – читайте здесь.
Данный подход использовал Вон Вернон в своей книге «Реализация методов предметно-ориентированного проектирования». Цель написания этой книги: дать возможность разработчикам совершить полет на самолете DDD (в детстве автор зачастую путешествовал со своей семьей на небольших самолетах). Вид с высоты дает более широкое представление о проблемах моделирования, не давая застрять в различных технических деталях. Наблюдая ландшафт DDD таким способом, можно осознать преимущества как стратегического, так и технического проектирования. Подробнее – под катом!
Полет осуществляется с помощью инструментов и шаблонов стратегического моделирования, таких как:
единый язык
, предметная область
, предметная подобласть
, смысловое ядро
, ограниченный контекст
, карта контекстов
. Именно о них и пойдет речь в этой статье.Проектирование с помощью тактических шаблонов, таких как, например,
сущность
, объект
, значение
, репозиторий
, событие
, агрегат
, представляют собой облегченный DDD. Хотя очень важно уметь использовать этот подход, эти шаблоны имеют в основном технический характер, и, чтобы увидеть общую картину DDD, необходимо первым делом научиться применять стратегические шаблоны на практике.Основной целью применения DDD является получение высококачественной модели программного обеспечения, которая будет максимально точно отражать поставленные бизнес-цели. Для реализации этого требуется объединение усилий как разработчиков, так и экспертов в предметной области. Создание дружной и сплоченной команды позволяет получить большое количество преимуществ для бизнеса. Обмен знаниями между членами команды снижает шансы появления «тайного знания» о модели, достигается консенсус между экспертами предметной области в отношении различных понятий и терминологии, разрабатывается более точное определение и описание самого бизнеса.
Для того чтобы уравнять разработчиков и экспертов предметной области, чтобы было гораздо проще обмениваться полезными знаниями о предметной области, подход DDD предлагает применять общий набор терминов, понятий и фраз, который будет использоваться в общении между членами команды, и который позже отразится в исходном коде результирующей программы.
Единый язык
Этот коллективный язык терминов называется
единый язык
(Ubiquitous Language). Это один из основных и самых важных шаблонов предметного-ориентированного проектирования. Это не бизнес жаргон, навязанный разработчикам, а настоящий язык, созданный целостной командой – экспертами в предметной области, разработчиками, бизнес-аналитиками и всеми, кто вовлечен в создание системы. Роль в команде не столь существенна, поскольку каждый член команды использует для описания проекта единый язык
. Процесс создания единого языка более творческий чем формальный, так как он, как и любой другой естественный язык, постоянно развивается, а те артефакты, которые вначале способствовали разработке полезного единого языка, со временем устаревают. В итоге, остаются только самые устойчивые и проверенные элементы. Чтобы перейти от экспериментов к точным знаниям, Вон Вернон в своей книге предлагает использовать следующие способы:- Создание диаграмм физической и концептуальной предметной областей и нанесение на них меток, обозначающих имена и действия. Такие диаграммы носят неформальный характер, поэтому нет смысла использовать формальное моделирование (как UML).
- Создание глоссария с простыми определениями, а также альтернативными терминами с оценкой их перспективности. Таким образом разрабатываются устойчивые словосочетания единого языка.
- Создание документации вместо глоссария. Эта документация будет содержать неформальные диаграммы или важные понятия, связанные с программным обеспечением.
- Обсуждение готовых фраз с остальными членами команды, которые не могут сразу освоить глоссарий или другие письменные документы.
Так как код будет развиваться достаточно быстро и его необходимо согласовывать с текущим вариантом единого языка, то можно позже отказаться от диаграмм, глоссария или другой документации.
Наиболее важное для разработчика – это умение слушать экспертов, получать максимальное количество полезных знаний о предметной области. В то же время, эксперты также должны прислушиваться к разработчикам и их пожеланиям. Команда учится и растет вместе, если она действует сплоченно, получая более глубокое понимание бизнеса.
Приведу несколько примеров из книги:
В команде, обсуждая модель применения вакцины от гриппа в виде кода, произносят фразу наподобие: «Медсестры назначают вакцины от гриппа в стандартных дозах». Возможные варианты развития событий:
Очевидно, что первый вариант совсем не оптимален, второй – лучше, но не учитывает некоторые важные концепции. Окончательный вариант наиболее приемлем для поставленной задачи.
Очень важно понимать, что в рамках предметной области смысл определенного термина или фразы может сильно отличаться. Существует некая граница, в пределах которой понятия
единого языка имеют вполне конкретное контекстное значение.
Ограниченный контекст
Эта концептуальная граница называется
ограниченный контекст
(Bounded context). Это второе по значимости свойство DDD после единого языка. Оба эти понятия взаимосвязаны и не могут существовать друг без друга.Итак,
ограниченный контекст
– это явная граница, внутри которой существует модель предметной области, которая отображает единый язык
в модель программного обеспечения. - В каждом ограниченном контексте существует только один
единый язык
. - Ограниченные контексты являются относительно небольшими, меньше чем может показаться на первый взгляд.
ограниченный контекст
достаточно велик только для единого языка изолированной предметной области, но не больше. - Единый значит «вездесущий» или «повсеместный», т. е. язык, на котором говорят члены команды и на котором выражается отдельная модель предметной области, которую разрабатывает команда.
- Язык является единым только в рамках команды, работающей над проектом в едином ограниченном контексте.
- Попытка применить
единый язык
в рамках всего предприятия или что хуже, среди нескольких предприятий, закончится провалом.
Для примера, следует рассмотреть контраст между терминами сводка (ассount) в контексте банковских услуг и в литературном контексте:
Контекст банковских услуг
Сводка поддерживает запись о дебиторских и кредиторских транзакциях, отображающих текущее финансовое состояние клиента с точки зрения банка > Сводка о текущих счетах или сводка о сберегательных счетах
Литературный контекст
Сводка – это совокупность литературных выражений об одном или нескольких событиях, произошедших за определенный период времени > На сайте amazon.com продается книга Into Thin Air: A Personal Account of the Mt. Everest Disaster
Различить типы сводок невозможно по именам. Но их можно различить исключительно по названиям их концептуальных контейнеров, т.е. соответствующих ограниченных контекстов.
Эти ограниченные контексты относятся к разным
предметным областям
. В следующем примере, одно и то же имя используется в пределах одной и той же предметной области
. В некоторых издательствах книги проходят разные этапы жизненного цикла, то есть книга проходит различные
контексты
.- Разработка концепции и предложения к изданию
- Контракт с автором
- Управление редакционным процессом
- Разработка макета книги, включая иллюстрации
- Перевод книги на другие языки
- Выпуск бумажных и/или электронных версий книги
- Маркетинг
- Продажа книги реализаторам и/или непосредственно покупателям
- Поставка экземпляров книги реализаторам или покупателям
В этом случае, не существует единственного способа разработки правильной модели книги. Например, до заключения контракта, название книги остается неопределенным и может измениться в процессе редактирования. Для маркетинга не нужно большинство из артефактов литературной и технической редакций, за исключением обложек и аннотаций, а для продажи книги необходимы только название, расположение склада, количество экземпляров, размер и вес. Чтобы избежать путаницы, в рамках подхода DDD необходимо использовать отдельные
ограниченные контексты
для каждой из стадий жизненного цикла. Модель книги в каждом контексте
значительно отличалась бы от всех других. Каждая команда определенного ограниченного контекста
говорит о книге и знает точно, чего хочет для своего контекста
. В примере выше используются различные
ограниченные контексты
в рамках одной предметной области
. Предметная область, предметная подобласть, смысловое ядро
Предметная область
(Domain) – это то, что делает организация, и среда, в которой она это делает. Разработчик программного обеспечения для организации обязательно работает в ее предметной области
. Следует понимать, что при разработке модели предметной области необходимо сосредоточиться в определенной подобласти
, так как практически невозможно создать единственную, всеобъемлющую модель бизнеса даже умеренно сложной организации. Очень важно разделять модели на логические разделенные предметные подобласти
(Subdomain) всей предметной области
, согласно их фактической функциональности. Подобласти
позволяют быстрее определить разные части предметной области
, необходимые для решения конкретной задачи.Также необходимо уметь определять
смысловое ядро
(Core domain). Это очень важный аспект подхода DDD. Смысловое ядро
– это подобласть
, имеющая первостепенное значение для организации. Со стратегической точки зрения бизнес должен выделяться своим смысловым ядром
. Большинство DDD проектов сосредоточены именно на смысловом ядре
. Лучшие разработчики и эксперты должны быть задействованы именно в этой подобласти
. Большинство инвестиций должны быть направлены именно сюда для достижения преимущества для бизнеса и получения наибольшей прибыли.Если моделируется определенный аспект бизнеса, который важен, но не является
смысловым ядром
, то он относится к служебной подобласти
(Supporting subdomain). Бизнес создает служебную подобласть
, потому что она имеет специализацию. Если она не имеет специального предназначения для бизнеса, а требуется для всего бизнеса в целом, то ее называют неспециализированной подобластью
(Generic subdomain). Эти виды подобластей
важны для успеха бизнеса, но не имеют первоочередного значения. Именно смысловое ядро
должно быть реализовано идеально, поскольку оно обеспечивает преимущество для бизнеса. Это и есть основа для стратегического проектирования при подходе DDD.
Пространство задач и пространство решений
Предметные области
состоят из пространства задач и пространства решений. Пространство задач позволяет думать о стратегической бизнес проблеме, которая должна быть решена, а пространство решений, сосредоточится на том, как реализуется программное обеспечение, чтобы решить бизнес проблему.- Пространство задач – части
предметной области
, которые необходимы, чтобы создатьсмысловое ядро
. Это комбинациясмыслового ядра
иподобластей
, которое это ядро должно использовать. - Пространство решений – один или несколько
ограниченных контекстов
, набор конкретных моделей программного обеспечения. Разработанныйограниченный контекст
– это конкретное решение, представление реализации.
Идеальным вариантом является обеспечение однозначного соответствия между
подобластями
и ограниченными контекстами
. Таким образом, объединяются пространство задач и пространство решений, выделяются модели предметной области в четко определенные области в зависимости от поставленных целей. Если система не разрабатывается с нуля, она часто представляет собой большой комок грязи
, где подобласти
пересекаются с ограниченными контекстами
.В качестве примера в книге Вона Вернона приводится
смысловое ядро
для небольшой компании, которая занимается розничной продажей в Интернете. Любой интернет-магазин может улучшить свое положение, если будет использовать механизм прогноза, который будет анализировать историю продаж и данные о запасах для получения прогноза спроса и конкретных объемов оптимальных запасов. (Компания не должна тратить деньги на товары, которые не имеют спроса и занимают дополнительную складскую площадь.) Именно это смысловое ядро
делает организацию гораздо более конкурентоспособной, способной быстро идентифицировать выгодные сделки и гарантировать необходимый уровень запасов. Пространство задач состоит из смыслового ядро
и подобластей
, связанных с закупкой и запасами, и которые отображены на этом рисунке:Это только часть
предметной области
, а не вся предметная область
, в которой работает организация. Пространство задач (смысловое ядро и подобласти) необходимо проанализировать. Модель закупок, изображенная на рисунке, представляет собой решение для смыслового ядро
. Модель предметной области будет реализована в явном ограниченном контексте
: контексте оптимальных закупок. Этот ограниченный контекст
однозначно соответствует одной подобласти
под названием смысловое ядро оптимальных закупок. Еще один ограниченный контекст
под названием контекст закупок будет разработан для уточнения технических аспектов процесса закупок и будет играть вспомогательную роль по отношению к контексту оптимальных закупок. Они обеспечивают взаимодействие с открытым интерфейсом системы ERP. Контекст закупок и модуль закупок ERP объединяются в служебную подобласть закупок. Сам модуль ERP является неспециализированной подобластью
, поскольку ее можно заменить на любую другую коммерческую систему закупок. Однако, она становится служебной подобластью
, если ее рассмотреть в сочетании с контекстом закупок в подобласти закупок. В соответствие с рисунком, контекст оптимальных закупок должен также взаимодействовать с контекстом товарных запасов, который управляет единицами хранения. Он использует модуль товарных запасов ERP, который находится в пределах служебной подобласти
товарных запасов. ERP-приложение состоит из различных модулей, которые мы рассматриваем как логические подобласти
, – это подобласти
товарных запасов и закупок. Эти модули и контексты запасов и закупок объединяются в служебные подобласти
.Итак, для оценки пространства задач в первую очередь необходимо:
- Определить, как выглядит стратегическое
смысловое ядро
- Какие концепции должны рассматриваться как часть
смыслового ядра
- Перечислить
служебные
инеспециализированные подобласти
.
Оценка пространства задач влияет на оценку пространства решений. Здесь необходимо думать уже о существующих и новых системах и технологиях. Надо думать в терминах четко отделимых физических
органических контекстов
, для которых ищется единый язык
. Следует:- Проанализировать существующее программное обеспечение на предмет повторного использования
- Определить средства, которые следует приобрести или создать
- Изучить интеграцию этих средств
- Определить, как перекрываются концепции и данные разных
ограниченных контекстов
- Определить, какой
ограниченный контекст
содержит концепции, относящиеся ксмысловому ядру
, и какие тактические шаблоны используются для его моделирования.
ограниченный контекст
состоит не только из модели предметной области
. Хотя модель это ее основной компонент. Если создается схема баз данных из модели, она также участвует в этом ограниченном контексте
. В то же время, если схема существовала ранее и в ней нарушен проект, эта схема не относится к ограниченному контексту
. пользовательский интерфейс
, который выражает модель, также относится к ограниченному контексту
. Также могут быть реализованы сервис-ориентированные конечные точки, которые также находятся внутри границы. И компоненты пользовательского интерфейса, и сервис-ориентированные конечные точки делегируются прикладным службам
, которые действуют как фасад
по отношению к модели. Эти службы
также находятся внутри границы ограниченного контекста
. Размеры
ограниченных контекстов
могут быть самыми разными. Главное, – чтобы модель демонстрировала богатство единого языка
в контексте
. В ней должно существовать столько концепций предметной области
, сколько необходимо для моделирования в пределах ограниченного контекста
– ни больше, ни меньше. Для того чтобы не пропустить ничего существенного, необходимо найти четкий и хороший критерий. Для этого можно использовать карту контекстов
. Таким образом мы подходим к третьему важному шаблону стратегического проектирования.Карта контекстов
Следуя подходу DDD, определенная команда должна создать собственную
карту
, которая отражает пространство решений, в которой находится эта команда. Эта карта
состоит из ограниченных контекстов
, а также интеграционных связей между ними. Пример:Эта
карта контекстов
(Context map) отображает текущее положение дел, а не то, что будет в будущем. Необходимо избегать формальностей в процессе создания карты
. Слишком большое количество деталей только мешает процессу создания. Естественный ход событий – совпадение границ контекстов с организационным делением команды. Люди, работающие вместе, разделяют один общий контекст модели.
После создания предварительной
карты контекстов
, ее можно детализировать путем определения отношений между контекстами
.Существуют такие отношения между
ограниченными контекстами
и отдельными командами проекта:партнерство
(Partnership). Когда команды в двухконтекстах
достигают успеха и терпят неудачу вместе, возникает отношение сотрудничества. Они должны сотрудничать в процессе эволюции своих интерфейсов, чтобы учитывать потребности обеих систем.общее ядро
(Shared kernel). Общая часть модели и кода образует тесную взаимосвязь. Обозначается четкая граница подмножества модели предметной области, которую команды согласны считать общей. Ядро должно быть маленьким. Оно не может изменяться без консультации с другой командой. Необходимо согласовыватьединый язык
команд.разработка заказчки-поставщик
(Customer-supplier development). Когда две команды находятся в отношении «нижестоящий и вышестоящий», и команды вышестоящие учитывают приоритеты нижестоящих команд.конформист
(Conformist). Когда две команды находятся в отношении «вышестоящий и нижестоящий», причем вышестоящая команда не имеет причин учитывать потребности нижестоящей команды. Нижестоящая команда учитывает сложность трансляции между ограниченными контекстами, беспрекословно подчиняясь модели вышестоящей команды.предохранительный уровень
(Anticorruption layer). Если управление и коммуникация не соответствуют общему ядру, партнеру, или отношению «Заказчик-поставщик», то трансляция является сложной. Нижестоящий клиент должен создать изолирующий слой, чтобы обеспечить свою систему вышестоящей системы в терминах своей модели предметной области. Этот уровень общается с другой системой с помощью существующего интерфейса, не требуя или почти не требуя модификаций другой системы.служба с открытым протоколом
(Open host service). Определяется протокол, который предоставляет доступ к системе как к набору служб. Для учета новых требований интеграции этот протокол расширяется и уточняется.общедоступный язык
(Published language). Трансляция между моделями двухограниченных контекстов
требует общего языка. В качестве среды для коммуникации используется хорошо документированный общий язык, который может выразить необходимую информацию о предметной области, выполняя при необходимости перевод информации с другого языка на этот.отдельное существование
(Separate ways). Если между двумя наборами функциональных возможностей нет важного отношения, их можно полностью отсоединить друг от друга. Интеграция всегда дорого стоит, а выгоды бывают незначительны.большой комок грязи
(Big ball of mud). Существуют части системы, в которых модели перемешаны, а границы стерты. Необходимо нарисовать границу такой смеси и назвать еебольшой комок грязи
.
Пример разработки
карты контекстов
можно взять из статьи Альберто Брандолини Strategic Domain Driven Design with Context Mapping.Сначала рисуется простая карта контекстов с границами и связью между
ограниченными контекстами
:В этих двух контекстах есть различия в концепциях с одинаковым названием. Например, Account в Web User Profiling – это учетная запись пользователя (логин и пароль). В то же время, для PFM Application (персональное управление финансами) – это сводка, описывающая текущее состояние клиента с точки зрения банка. Иногда, как было указано выше, одна и та же концепция может использоваться в абсолютно разных
контекстах
, тем самым для них необходимо определить разные модели.Например, PayeeAccount – это тот же BankingAccount, но с другим поведением (нельзя получить баланс). Таким образом будет создан отдельный контекст учета расходов (expense tracking). Также отдельно, в приведенном примере, создается контекст онлайн сервисов банка (on-line banking services) (такие сервисы, например, как распечатка выписок банка).
После первого шага создания
карты
, можно детализировать все отношения. У каждого отношения есть направление. Вышестоящие (upstream) влияют на нижестоящие (downstream), но не факт, что обратное верно. Детализированная
карта
выглядит вот так: Контекст банковских онлайн сервисов предоставляет API (это может быть служба с открытым протоколом и общедоступный язык). При изменении этого API, контекст персонального управления финансами должен тут же измениться, чтобы работать с новым API. При этом необходимо использовать
предохранительный уровень
, чтобы не дать понятиям из контекста онлайн сервисов просочиться в контекст персонального управления финансами (делается преобразование моделей предметной области). Так как контекст профайлов веб-пользователей используется как готовый внешний модуль и он поставляется «как есть», здесь устанавливается отношение
конформист
(нижестоящий подчиняется вышестоящему). В случае с контекстом учетов расходов, то здесь лучше всего подходит отношение
партнерства
, так как существуют общие цели и концепции, но нет направления отношения. Это простой пример
карты контекстов
, на деле они бывают намного сложней.Вывод
В этой статье были рассмотрены основные понятия предметно-ориентированного проектирования с помощью стратегических шаблонов:
единый язык
, ограниченный контекст
, предметная область
, предметная подобласть
, смысловое ядро
, карта контекстов
. Этих инструментов достаточно, чтобы увидеть стратегическое развитие проекта и понять, как дальше развивать бизнес, чтобы добиться наибольшего успеха. Конечно, после прочтения данной статьи многое еще захочется уточнить. Для этого рекомендую обратиться к вышеупомянутой книге Вона Вернона. Также для этого существуют специальные сообщества, куда можно обратиться за советом. Тактические же приемы моделирования, а также шаблоны, такие как
сущности
, объекты значения
, агрегаты
и другие будут рассмотрены в следующей статье.Спасибо за внимание!
Статью подготовили: greebn9k (Сергей Грибняк), wa1one (Владимир Ковальчук), silmarilion (Андрей Хахарев).
Комментарии (57)
indestructable
30.11.2016 15:30Спасибо за статью.
Было бы интересно почитать про выражение и преобразование концептуальной архитектуры в код.
greebn9k
30.11.2016 16:07Если вы имеете в виду, как реализовывать конкретные ограниченные контексты технически, то об этом вторая статья. Там будут конкретные тактические шаблоны с кодом. А если вы про архитектуру всей системы, то она бывает трехуровневой или гексагональной, например. DDD подход пригоден при любой архитектуре
symbix
30.11.2016 16:10+2На практике замечаю, что даже изначально спроектированный по канонам DDD проект со временем имеет тенденцию вырождается в геттерно-сеттерную анемичную фигню по множеству причин — дедлайны, проблемы с производительностью, ну и, конечно, новые разработчики, привыкшие к фреймворкам типа рельсов.
Кажется, это во многом происходит из-за того, что не хватает чисто практических примеров. У людей, привыкших к геттерно-сеттерно-анемичным псевдо-mvc-архитектурам и прочитавшим книжку по DDD, часто возникают проблемы не с пониманием абстрактной концепции bounded context или aggregate root, а совсем иного рода — как сгенерировать автоинкрементный id, как отправить письмо после регистрации, что делать с зависимостями моделей (double dispatch? events?) и так далее :-)greebn9k
30.11.2016 16:47Для согласованности в системе используются события. Отправить письмо — это инфрастуктурные вопросы.
Если следовать единому языку, то функции установщики будут очень редко использоваться.symbix
30.11.2016 23:21+2Сама отправка — да, а вот содержимое письма вполне может определяться бизнес-логикой. ;)
Что такое «функции-установщики»? Давайте, может, англоязычными терминами оперировать? Так понятнее.greebn9k
01.12.2016 11:38Функции установщики — setters, я имел ввиду что если используется единый язык, то анемия пропадает, очень редко будут необходимы функции сеттеры
lair
01.12.2016 12:18+1Эмм, если анемия пропадает, нетривиальные сеттеры как раз и появляются. А вот в анемичных моделях сеттеры как раз вырожденные.
Более того, единый язык никак не связан с анемичностью модели. Можно иметь анемичную модель и пользоваться единым языком, можно иметь не-анемичную модель и не пользоваться единым языком.
greebn9k
01.12.2016 13:06Я привел пример с книги про медсестер. Если используется единый язык, то сеттеры пропадают, таким образом слой сервисов приложений становится более тонким, модель перестает быть анемичной.
Приведите пример анемичной модели с использованием единого языка.lair
01.12.2016 13:13Если используется единый язык, то сеттеры пропадают,
Почему?
Приведите пример анемичной модели с использованием единого языка.
class Person { string FirstName; string LastName; }
greebn9k
01.12.2016 13:59В рамках DDD подхода объекты такого класса не создаются вообще. Это должна быть сущность или агрегат со своими поведенческими функциями. Ну здесь не только DDD не выполняется а и ООП инкапсуляция, думаю так
lair
01.12.2016 14:00+1Вот только ни то (DDD), ни другое (ООП) не является обязательным условием для использования единого языка.
indestructable
01.12.2016 14:28Поддержу.
Rich model vs Anemic Model — это деталь реализации, со своими достоинствами и недостатками.
symbix
01.12.2016 16:59Странная у вас DDD-практика. Сеттеры в моделях — это разновидность инъекции, так делать вообще не стоит никогда.
Я имел ввиду не сеттеры, а double dispatch.
indestructable
30.11.2016 17:45+1Хмм, а разве DDD это про реализацию? Сервисную или веб архитектуру удобно делать анемичной, чтобы не хранить состояние.
symbix
01.12.2016 00:59+1Веб-архитектуру удобно делать анемичной только в примитивных проектах, где бизнес-логики почти нет.
Всё про реализацию, на самом деле. Если не знаешь, как сделать инфраструктурную и application части, что толку от domain model? На голой теории далеко не уедешь.indestructable
01.12.2016 14:28+1Любую бизнес-логику можно описать и при помощи rich model, и при помощи anemic model.
symbix
01.12.2016 17:09+1anemic model не описывает никакой логики, это вообще тупо структура.
Описать можно в сервисах, но есть мнение, что это не ООП, а обычное процедурное программирование с ООП-синтаксисом. Я не говорю, конечно, что это всегда однозначно плохо — бывает, что и неплохо, но не ООП.indestructable
01.12.2016 18:28В сервисах описать, да. ООП в сервисах есть, разве что наследование не используется широко. Или, по-вашему, ООП это только когда мы пишем
order.Save()
вместоorderService.Save(order)
?symbix
01.12.2016 18:46orderService.save(order) — это выглядит как ООП.
А вот какой-нибудь order.amount = 100 — не. Анемичный сеттер — то же самое.lair
01.12.2016 19:02А вот какой-нибудь order.amount = 100 — не [ООП]
Почему нет-то?
symbix
02.12.2016 02:44Потому что ООП — это когда this.amount = 100
VolCh
02.12.2016 08:57order = this.orders.last();
order.amount = 100;symbix
02.12.2016 10:07Имеется ввиду то, что это в aggregate root, да?
В принципе, вполне допустимо. Но вообще сведение всей логики в aggregate root и использование некорневых моделей чисто как anemic/persistence models — это, на мой взгляд, такой DDD-шный антипаттерн, последствие анемичного мышления с сервисами. Перекинули код из сервиса в AR и все.
lair
02.12.2016 10:58Прекрасный аргумент, да.
Вот у меня есть банальная совершенно ситуация, строчки заказа, состоящие из {товар, количество} (единицы измерения не учитываем, везде штуки). Пользователь количество вводит руками в UI. Почему проставить его в соответствующее свойство соответствующего объекта — это не ООП?
symbix
02.12.2016 16:12-1http://www.martinfowler.com/bliki/AnemicDomainModel.html
lair
02.12.2016 16:14Там нет ответа на этот вопрос. Более того, за свойством
Amount
вполне может быть поведение.symbix
02.12.2016 17:44+1Давайте обойдемся без рассматривания языков, где есть костыли типа property setters (тем более, что от этого лучше не становится).
Ответ там есть:
The fundamental horror of this anti-pattern is that it's so contrary to the basic idea of object-oriented design; which is to combine data and process together.
order.amount = 100 — это чистая процедурщина со структурами, никакого бизнес-действия за этим нет. order.setAmount(100) — то же самое.
Заказ без суммы вряд ли бывает, так что первично amount передается в конструкторе. А для изменения нужна какая-то причина, выраженная на языке предметной области, которая должна быть отражена в имени метода.
>Пользователь количество вводит руками в UI. Почему проставить его в соответствующее свойство соответствующего объекта — это не ООП?
Потому что мыслить надо бизнес-действиями, а не полями, структурами и таблицами в базе данных. За любым вводом в UI скрывается какое-то действие.lair
02.12.2016 17:49order.amount = 100 — это чистая процедурщина со структурами, никакого бизнес-действия за этим нет.
Я выше привел пример случая, когда за этим есть бизнес-действие (только не для заказа, а для строчки заказа):
Вот у меня есть банальная совершенно ситуация, строчки заказа, состоящие из {товар, количество} (единицы измерения не учитываем, везде штуки). Пользователь количество вводит руками в UI.
А для изменения нужна какая-то причина, выраженная на языке предметной области, которая должна быть отражена в имени метода.Причина называется "покупатель сказал, сколько хочу".
VolCh
02.12.2016 18:36Строка типа order.amount = 100 ничего не говорит нам о том Rich Model это или Anemic, а может DTO, ООП это или не ООП. Она вполне может находится в одном из методов order, она может находить в фабрике или конструкторе, она может являться частью публичного интерфейса сущности Rich Model, а может внутреннего.
indestructable
03.12.2016 19:21Воувоу, сумма заказа передается в конструкторе? Сумма заказа обычно рассчитывается, причем по довольно сложным правилам. И у нее есть определенные моменты пересчета (и совсем не обязательно, чтобы это был момент установки какого-то свойства).
Тема холиварная, конечно. Анемичная модель удобна для сервис-ориентированных stateless приложений, т.к. anemic легче сделать стейтлесс. Принципиальной разницы нету, вообще.
VolCh
01.12.2016 22:09Вполне себе ООП и даже вполне может быть по DDD. Если в домене есть операция установки суммы ордера, то она вполне может выглядеть так. Особенно если эта операция происходит в корневом агрегате.
sentyaev
30.11.2016 17:40+1Позанудничаю.
Скажите пожалуйста, у вас есть разрешение издательства Addison-Wesley на воспоизведение их материаллов? (В книге указано, что использование материалов возможно только с согласия издательства)
В этой статье вы использовали изображения со страниц 70, 110 и 115 книги «Реализация методов предметно-ориентированного проектирования» Вон Вернон.greebn9k
02.12.2016 12:28+1Спасибо за дельное замечание. Картинки поменяли. Пример взят из книги, а картинки свои… уже.
Lofer
01.12.2016 11:30Не могли бы Вы прояснить свою мысль, или пояснить подробнее:
Такие диаграммы носят неформальный характер, поэтому нет смысла использовать формальное моделирование (как UML).
при этом
чтобы было гораздо проще обмениваться полезными знаниями о предметной области, подход DDD предлагает применять общий набор терминов, понятий и фраз, который будет использоваться в общении
и
. В итоге, остаются только самые устойчивые и проверенные элементы.
Т.е формально, декларируется: давайте изобретем свою семантику и нотацию для нашего проекта, потому что…
Тот же UML не запрещает расширять свою семантику и нотацию, если ее не хватает. (Хотя ее часто не хватает, для специфических вещей :) )
Возникает вопрос: Зачем изобретать свою семантику и нотацию, если стандартные средства и инструменты не запрещают и позволяют расширять существующие общеизвестные?
Nashev
13.03.2017 20:04Оксид графена??
lair
01.12.2016 15:01На самом деле, "единый язык" просто никак не связан с нотацией. Можно использовать единый язык и использовать UML, можно использовать единый язык и не использовать стандартные нотации. Это разные уровни семантики.
stalinets
13.03.2017 20:40Вот кстати, на рубеже веков, когда я был школьником, во всех ларьках с газетами-журналами продавались голографические зелёные с нотками жёлтого наклейки, похожие на второе изображение в статье. Разных размеров и с разными сюжетами. Мы их клеили на пеналы, учебники и т.д. А сейчас их в продаже как-то нет, по крайней мере в моём городе.
Интересно, почему они исчезли? Почему не сделать то же самое, но цветное? Можно ли сделать недорогой принтер, который сможет печатать такие голограммы, используя для этого пару десятков фото с разного ракурса или 3D-файл с компьютера?lair
01.12.2016 15:21Почему высокоуровневая «над проектная» абстракция обязательно должна быть разная на разных проектах?
Потому что единый язык — это не абстракция. Это конкретный словарь, создаваемый под каждый проект и строго соответствующий его домену.
Lofer
01.12.2016 15:47Единый язык — это глоссарий и конкретные сущности проекта. По этому вопросу нет.
вопросы по:
Такие диаграммы носят неформальный характер, поэтому нет смысла использовать формальное моделирование (как UML).
Народ лет 10...25 изобретал UML, BPMN, IDEFx и т.д. все они в той или иной степень детализации могут нарисовать что угодно (вопрос цены работы и инструмента)
Чем этот «смысл» измеряется?
Нужно исбегать формальных способов описания единого языка, не только UML. Это сковывает и разработчиков и экспертов. Построение единого языка — процесс более творческий, чем формальный.
Но почему нужно избегать формализации, если конечная цель «корректность» построенного и простота верификации результат на его корректость и целостность.
Без формализации это, весьма затруднительно. А если учесть что «результат» должен быть прочитан третьей стороной «без усилий», то это выглядит странно еще и экономически.
Это вроде как: давайте этот проект сделаем на китайском, это на хинди, этот клинописью, этот узелковым письмом, а этот вообще на языке запахов и цвета. Но никоем образом не будем делать все проекты на русском или английском языке.lair
01.12.2016 15:57Народ лет 10...25 изобретал UML, BPMN, IDEFx и т.д. все они в той или иной степень детализации могут нарисовать что угодно (вопрос цены работы и инструмента)
"Смысл" измеряется стоимостью усилий по использованию инструмента (стоимость инструмента + стоимость специалиста) в сравнении со стоимостью выигрыша от использования этого инструмента.
Опыт показывает, что для большей части случаев формальные нотации для описания домена избыточны.
А если учесть что «результат» должен быть прочитан третьей стороной «без усилий»,
Как раз наоборот. Если вы используете UML, вам надо, чтобы ваша третья сторона умела читать UML. Если вы используете примитивную нотацию, вам достаточно объяснить эту нотацию.
Lofer
01.12.2016 16:12Вообще-то без разницы что учить третьей стороне: самопальную нотацию или «стандартизированную». Были прецеденты.
То же UML говорит: вы можете нарисовать что угодно и как угодно, только задекларируйте свою нотацию. Вроде как для XML: задекларируйте схему документа, если не хотите проблем.
Самопальная нотация, как правило не учитывает нюансы, заложенные для «самопроверки» результата грамотными людьми при создании «взрослых стандартных» нотаций. Как правило их просто нет, что выливается в конкретные проблемы у конкретного программиста или QA.
Те же «взрослые стандартные нотации» поддерживаются инструментарием.
Те же «взрослые стандартные нотации» поддерживают расширения, если «маловато будет».
Можно где-то глянуть примеры «избыточности стандартной нотации» и «разумной достаточности» для сравнения?lair
01.12.2016 16:16Вообще-то без разницы что учить третьей стороне: самопальную нотацию или «стандартизированную».
Разница в объемах.
Можно где-то глянуть примеры «избыточности стандартной нотации» и «разумной достаточности» для сравнения?
Для описания доменной модели достаточно (в рамках одного bounded context) ровного одного примитива (доменная сущность) и двух типов связи (ссылка и композиция), причем для ссылки нужно знать направление и семантику связи. Все.
Честное слово, я не хочу изучать (или заставлять кого-то изучать) UML, чтобы рисовать схемы, которые укладываются в описанную выше нотацию.
VolCh
01.12.2016 21:53Нет такой конечной цели при выработки единого языка, контекстов и сопутствующих артефактов типа диаграмм отношений. Непротиворечивость и прочая логичность на этом этапе лишь бонус. Если он получен бесплатно — хорошо. Если надо тратить ресурсв на формализации и верификации, то обычно овчинка выделки не стоит, слишком часто эта часть документации меняется.
Lofer
02.12.2016 00:36Непротиворечивость и прочая логичность на этом этапе лишь бонус
По идее это конечная цель.
Если упоминается какая-то сущность А в связи с сущность Б, при этом описана только сущность А, без Б то зачем такой результат?
Если описана сущность В без атрибутов, с припиской «должна быть корректна» а чему корретна? ХЗ. Нафига такой результат?
Если указывается бизнес процесс без начала и/или конца или одной ветки логики, и/или участвующих сущностей, участников — то зачем такая работа?
Это просто «поток сознания» не имющий практической ценности.
Если надо тратить ресурсв на формализации и верификации, то обычно овчинка выделки не стоит, слишком часто эта часть документации меняется.
Для этого есть специфическое ПО.
Это как сказать: программист то код набил? набил. А что этот код не компилируется — фигня, все равно «слишком часто эта часть документации меняется»VolCh
02.12.2016 14:48+1Конечная цель создания единого языка — общение членов команды на нём, в том числе для выработки, если необходимо, формальных описаний сущностей, процессов и т. д. Собственно детальных атрибутов на этапе формирования языка нет. И да, в какой-то мере, это просто поток сознания.
Нужно тратить ресурсы на обучение всех членов команды формальному языку, нужно тратить ресурсы на ПО, нужно тратить ресурсы на устранение незначимых на данном этапе противоречий, неполноты и прочих дефектов формального артефакта.
Единый язык — это не результат работы, он даже может не быть частью даже рабочей документации в явном виде. Даже явный глоссарий имеет вспомогательную роль, а уж диаграммы его поясняющие можно от руки рисовать — они не описывают полностью сущности или процессы, они служат средством подтверждения того, что у всех членов команды единое понимание языка. Например, что клиент — это человек, совершивший покупку. На данном этапе не важно, например, может ли он совершить много покупок, просто фиксируется связь типа «совершил» между сущностями «клиент» и «покупка». Есть связь — клиент, нет — просто человек. Формальные инструменты заставят вас детально описывать сущности и связь, хотя сейчас вам это не важно, вам нужно только понять какие сущности вообще есть и какие между ними связи. Хотя бы чтобы понятно всей команде написать имена этих сущностей на формальной диаграмме, когда решите её создавать. Если вы показываете формальную верифицированную диаграмму, а первый вопрос у хотя бы одного члена команды: «а Customer — это что?» — значит ві слишком рано начали использовать формальніе инструменті.Lofer
03.12.2016 00:17Если вы показываете формальную верифицированную диаграмму, а первый вопрос у хотя бы одного члена команды: «а Customer — это что?» — значит ві слишком рано начали использовать формальніе инструменті.
Вполне закономерый вопрос — а кто-что такое Customer?
Если нету в глоссарии, нету в диаграммах, если не понятен его жизненный цикл, не понятен его функционал — зачем это техническому спецу (программисту разработчику архитектору, qa)?
Это получается «сферический конь в вакууме». Traceability failed. фиксить.
Нужно тратить ресурсы на обучение всех членов команды формальному языку,
Увы, но это в любом случае придется делать, если ожидаете от них какой-то вменяемой обратной связи. Иначе зачем вы вовлекаете других людей в свою песочницу?
Проблема в том, что софт, это в любом случае формализация.
значит ві слишком рано начали использовать формальніе инструменті
В какой-то момент у вас в руках, например, бумажный билетик, на котором написанно 10 денег. И в какой-то момент возникает вопрос: а эти «10 денег» это что ?! Откуда оно? и как выглядит? как Amount + Currency или String и как это отобразить на «физику»?
Это провоцирует вопрос: А когда нормально или поздно для «формальніе инструменті»? Когда подписан бюджет проекта? когда будете пытаться генерить скрипты sql для базы или wsdl схемы? когда QA будет пытаться сделать User Accepted Tests?
И как вы будете перетягивать из «нефомальных тулзов» в «формальные тулзы» если неформальные заняли 340 часов и за чей бюджет?VolCh
03.12.2016 09:25Если нету в глоссарии, нету в диаграммах, если не понятен его жизненный цикл, не понятен его функционал — зачем это техническому спецу (программисту разработчику архитектору, qa)?
Чтобы понимать бизнес, как минимум.
Увы, но это в любом случае придется делать, если ожидаете от них какой-то вменяемой обратной связи. Иначе зачем вы вовлекаете других людей в свою песочницу?
Не придётся. Грубо, они привлекаются, чтобы точно и однозначно составить ТЗ, а если где-то какие-то умолчания и допущения, то они должны быть расшарены между всеми членами команды.
И как вы будете перетягивать из «нефомальных тулзов» в «формальные тулзы» если неформальные заняли 340 часов и за чей бюджет?
Во-первых, не факт, что такое перетягивание нужно, если не считать перетягиванием непосредственно написания кода. Во-вторых, DDD с точным следованием — дело дорогое, это долгосрочные инвестиции.Lofer
03.12.2016 13:48Чтобы понимать бизнес, как минимум.
Это слишком оптимистично сказано :) Сомневаюсь, что найдется Клиент, который будет готов оплатить изучение всей командой всей нормативной базы, на основе которой строится его бизнес. Даже если опустить вопрос денег, встает вопрос времени на изучение. Неделю — могут позволить на «познакомиться с выжимкой», но не 6...12 месяцев!
Полагаю «Понимать в рамках, необходимых для решения бизнес- проблемы Клиента» будет корректнее.
Это бизнес аналитика, и кусок ALC.
И она как раз формализуется и верифицируется при корректном подходе и инструментарии и своя нотация ко всему этому есть. (в нескольких вариантах)
Если вы хотите получить конкрентное пояснение «откуда это» или «а кто это сделал и почему» — вам придется это делать. В противном случае, на более-менее серьезном проекте, вам зададут вопрос или юристы или фин директор или работники — а за чей счет банкет? или клиент задаст вопрос — что за фигню вы мне сваяли и если не сможете внятно ответить, еще и неустойку по контракту заплатите (плюс репутационные риски).
Для мелких «сервисных» проектов ~ 10 тыс часов, когда все носители знания под рукой и без поддержки пару лет — такие объяснения еще могут прокатить. Для больших — сомнительно.
Для продуктовых проектов — тоже сомнительно.
ihostage
03.12.2016 00:58+2Я возможно что-то упускаю из виду. Скажите, в этой статье есть что-то, чего нет в The Big Blue Book Эванса или в той же книге Вернона, на которую вы сами ссылаетесь? Или в материалах, перечисленных в этой статье https://habrahabr.ru/post/61524/ семилетней давности?
Сначала обрадовался заголовку в ленте. Ожидал разбора классных кейсов в нестандартных доменах. А ощущение, что почитал ещё ужатый InfoQ: DDD Quickly.
greebn9k
03.12.2016 12:08В семилетней статье нету, например, описания что такое служебная подобласть (Supporting Subdomain).
Этого нету и в DDD Quickly. Пример карты контекстов выбран не с этих книг.
ihostage
03.12.2016 13:06В семилетней статье нету, например, описания что такое служебная подобласть (Supporting Subdomain). Этого нету и в DDD Quickly.
В вашем случае служебная подобласть не тоже самое, что GENERIC SUBDOMAINS? О которых рассказывается и в оригинальной книге Эванса и упоминается в InfoQ (что логично, учитывая что это просто краткое содержание оригинала)? Из вашего описания, я не увидел между ними никакой разницы, если объясните, буду признателен.
awedov
Объемная и интересная статья. Без воды и с хорошими примерами. Сразу видно, что писал разработчик.