Domain driven design что это

Поваренная книга разработчика: Domain Driven Design рецепты ( 2-я часть, структура и взаимодействие )

Domain driven design что это. Смотреть фото Domain driven design что это. Смотреть картинку Domain driven design что это. Картинка про Domain driven design что это. Фото Domain driven design что это

Введение

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

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

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

Вспомним данное ранее определение:

Проектирование на основе предметной области (DDD, Domain-driven design) — это подход к разработке программного обеспечения для комплексного удовлетворения потребностей, путем сильной связи реализации с основными бизнес-моделями, находящимися в процессе постоянного развития.

Эталонной книгой которая описывает практики построения сложных систем является книга Domain Driven Dedign (Big Blue Book) Эрика Эванса. Если вы читали любую обзорную статью по этой теме, вы уже знаете об этом. К моменту применения DDD на практике вам придется ее прочесть. Это не самая легкая книга для восприятия:

The canonical source for DDD is Eric Evans’s book. It isn’t the easiest read in the software literature, but it’s one of those books that amply repays a substantial investment.

Martin Fowler: 15 January 2014

Если пролистать содержание книги, она покажется вам не совсем структурированной. Но нам поможет карта.
Domain driven design что это. Смотреть фото Domain driven design что это. Смотреть картинку Domain driven design что это. Картинка про Domain driven design что это. Фото Domain driven design что это

На карте выделены те практики, которые мы сегодня рассмотрим.

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

Единый язык

Разработка программного обеспечения редко приводит к созданию чего-то нового, как правило, это моделирование чего-то существующего.

Модель — представление реального объекта, включающее в себя только необходимые свойства и функции.

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

Хорошим примером модели будет являться топографическая карта. Она является моделью местности. Карта не содержит лугов полей и рек, она только отражает месторасположение реальных объектов относительно друг друга.

Чтобы построить четкую и ясную для всех модель, нужно говорить на одном языке. Об этом нам говорит не только Эрик Эванс, но и здравый смысл. Если программисты будут использовать свои термины, а бизнес свой ‘сленг’, то первые просто не будут понимать что нужно делать. Бизнес же в этом случае не сможет осознать реальной стоимости разработки той или иной ‘фичи’. Сколько раз вам приходилось слышать: «Да это всего лишь добавить кнопку»?

Ваша цель, как проектировщика системы, должна быть в том, чтобы добиться от всей команды максимального понимания друг друга. Как же этого добиться? Начните говорить. Если люди начинают общаться в любой тесной группе, у них появляется некий общепринятый набор терминов. В различных компаниях процесс введения общего языка, скорее всего, будет отличаться. Это может быть как волевым решением, так и демократической процедурой. Язык может быть обозначен явно, так и вводиться не явно, в этом случае на нем начинают просто говорить. Хорошим приемом введения общего языка станет общая документация.

Как вести документацию проекта

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

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

– Необыкновенно ясно изложено! – восхищались абдериты. – Удивительно ясно! – Они полагали, что понимают философа, так как очень хорошо знали, что такое луковица.

История Абердитов, Кристов Мартин Виланд

Ограниченный контексты и домены

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

Давайте вспомним документацию, которую мы описывали в предыдущей главе. Там в нашем едином словаре использовался термин регистрация. Но в данном проекте мы имеем их несколько:

Унифицированный язык принадлежит к ограниченному контексту. Домен приведенной выше документации — ‘Система авторизации’. Давайте попробуем выделить домены для нашего стартапа.

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

Домен (Domain) — это репрезентация реальной бизнес структуры, решающая определенную задачу.

Например: Система логистики, Система оплаты, Система авторизации, Система управления заказами.

Домен делится на сабдомены, которые описывают меньшие структуры, например: корзина заказов, система построения маршрутов.

Каждый домен имеет ограниченную зону ответственности — лимитированную функциональность.

Ограниченный контекст (Bounded context) — набор ограничений домена, помогающий сфокусироваться домену только на одной задаче для ее лучшего решения.

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

Domain driven design что это. Смотреть фото Domain driven design что это. Смотреть картинку Domain driven design что это. Картинка про Domain driven design что это. Фото Domain driven design что это

Еще в терминологии DDD выделяют ядро.

Ядро (Core domain) — самый главный домен, наиболее емко характеризующий ваш бизнес.

Итак, домены проекта «Четыре черепахи и одна крыса»:

Работа с пиццерией (Pizzarias)

Контекст: b2b все, что относится к работе с пиццериями

Работа с клиентом (Clients)

Контекст: b2c, все что относится к работе с заказчиками пиццы

Работа с курьерами (Delivery system)

Контекст: b2e, все что относится к работе с курьерами

Система заказов (Order system)

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

Система рассчетов (Billing)

Контекст: Содержит в себе все финансовые операции. Обеспечивает взаимодействие с процессинговым центром.

Система статистки (Statistics)

Контекст: Сбор и обработка (не выдача) аналитической информации.

Система менеджмента (Managment panel)

Контекст: Выдача аналитической информации. Инструментарий управленческих решений.

На основе доменов давайте составим его карту.

Карта доменов (Context map) — графический инструмент, который позволяет описать связи между отдельными доменами.

Domain driven design что это. Смотреть фото Domain driven design что это. Смотреть картинку Domain driven design что это. Картинка про Domain driven design что это. Фото Domain driven design что это

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

Самое важное в карте — мы видим связи межу доменами. Такая структура очень хорошо ложится на микросервисную архитектуру:

Главный принцип микросервисной архитектуры: слабая связанность и сильное сцепление.

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

Перевод данных терминов взят из официального русского перевода и, возможно, плохо отражает передаваемый смысл. В оригинале термины звучат как: Low coupling (связанность, зацепление, сцепление, сопряженность), high cohesion (связность, прочность).

Практика реализации доменного разделение

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

Основные принципы, которыми мы руководствовались:

Как реализовать домены?

Очень удобно выделять домены как отдельные микросервисы.

Микросервисы — это отдельное приложение, реализующее логику одного домена.

В DDD-разработке принципом выделения микросервиса в отдельное приложение будет служить ограниченный контекст. Это не отменяет технический принцип разделения сервисов (если это обусловлено необходимостью обеспечения высокой производительности). Но контекстный принцип будет доминирующим и обязательным.

Как выделить связи между доменами?

Связи между доменами это всегда API. Это может быть RESTful json api, gRPC, AMPQ. Мы не будем в рамках данной статьи сравнивать один протокол с другим и выделять их преимущества и недостатки, у каждого из них есть своя область применения. Но все же, остановимся на общих рекомендациях:

Будте гибкими в выборе протокола и жесткими в однотипности его реализации.

Выбирайте протокол для каждой пары доменов индивидуально, не старайтесь везде использовать http, возможно, вам где-то понадобится асинхронные очереди и преимущества AMPQ для вас станут очевидными. Не игнорируйте эту возможность потому, что у вас везде RESTful.

С другой стороны, если вы реализуйте RESTful json, используйте один стандарт структуризации данных. Можете взять готовый например jsonapi или openapi. Если по каким-то причинам готовые решения вас не устраивают и вы чувствуете, что можете разработать свой стандарт — опишите и используйте его. Но применяйте его везде, не разводите «зоопарк» стандартов. Если вам нужно общаться с внешней системой, где про ваши стандарты ничего знают, напишите микросервис адаптер.

Domain driven design что это. Смотреть фото Domain driven design что это. Смотреть картинку Domain driven design что это. Картинка про Domain driven design что это. Фото Domain driven design что это

Как реализовать сабдомены?

Как отдельные модули внутри микросервиса.

Модуль — это реализация сабдомена, путем вынесения логики в отдельное пространство имен (Namespace) в рамках одного микросервиса.

Как это все выглядит? Давайте рассмотрим на примере. Как мы помним, у нас есть домен Работа с курьерами (Delivery system) — у этого домена есть три сабдомена:

Представим это все в виде структуры папок:

Каждый такой паттерн реализован в соответствующем пространстве имен (Namespace). Например форма создания завяки на выплату курьеру:

Как реализовать связи между сабдомены?

У нас есть два Процесса при исполнении которых мы обращаемся к этой учетной записи.

Как мы видим эти два процесса относятся к разным сабдоменам — Registration и Wihtdrawal.

Реализация через модель.

Процитирую Эрика Эванса:

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

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

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

Источник

Домен, поддомен, ограниченный контекст, пространство задач/решений в DDD: четко определены

Domain driven design что это. Смотреть фото Domain driven design что это. Смотреть картинку Domain driven design что это. Картинка про Domain driven design что это. Фото Domain driven design что это

Domain-Driven Design — это, как правило, подход к проектированию систем программного обеспечения, который предполагает создание общего языка между экспертами домена и разработчиками системы. В число известных правил DDD входят Use a Ubiquitous Language и Make The Implicit Explicit.

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

Данная статья подготовлена в результате длительной беседы на github с участием многих представителей сообщества DDD. Спасибо всем участникам этого диалога за сотрудничество.

Неявно, но не двусмысленн

Прежде чем дать определение каждому термину, я хочу отметить важную мысль, которую высказывает Kenny Baas-Schwegler. Он утверждает, что DDD должен быть неявным. Благодаря неявности DDD мы можем исследовать, моделировать и решать все новые и новые проблемы, потому что существующие шаблоны и принципы не ограничивают наше мышление.

Под неявностью я подразумеваю, что слово можно использовать для описания различных вещей, которые в чем-то похожи, но не идентичны. Хорошим примером является слово «немного». В некоторых вариантах оно может означать небольшой диапазон, например 2-3, а в иных может означать другой диапазон, например 5-10. В прочих случаях оно может означать 100 фунтов стерлингов: «Не могли бы вы одолжить мне несколько фунтов?». Главное, чтобы неявность хорошо выводилась из контекста (если разные люди интерпретируют его существенно по-разному, это слишком двусмысленно).

Если я говорю слово и ожидаю, что у вас будет такое же определение, а в действительности получается совсем другое, то мы имеем ложную согласованность. Мы думаем, что говорим об одном и том же, но это не так.

Domain driven design что это. Смотреть фото Domain driven design что это. Смотреть картинку Domain driven design что это. Картинка про Domain driven design что это. Фото Domain driven design что этоПредоставлено: Jeff Patton https://www.jpattonassociates.com/read-this-first/

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

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

Домены

Domain-Driven Design тесно связан с определением домена в Кембриджском словаре:

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

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

Domain driven design что это. Смотреть фото Domain driven design что это. Смотреть картинку Domain driven design что это. Картинка про Domain driven design что это. Фото Domain driven design что этоКак сгруппировать эти концепты в домены?

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

Мы можем сгруппировать квадратные фигуры в домен Squares, а круги — в домен Circles. Однако синий квадрат и синий круг также могут принадлежать домену Blue.

Domain driven design что это. Смотреть фото Domain driven design что это. Смотреть картинку Domain driven design что это. Картинка про Domain driven design что это. Фото Domain driven design что это

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

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

Поддомены

В чем разница между доменом и поддоменом? Здесь все просто — поддомен не является словом, которое существует в словаре. Слово поддомен широко используется в мире веб-хостинга, но что оно означает в DDD?

В DDD поддомен — это относительное понятие. Домен и поддомен могут использоваться как взаимозаменяемые термины. Когда мы используем слово поддомен, то подчеркиваем, что домен, о котором говорится, является дочерним по отношению к другому домену более высокого уровня, который мы идентифицировали.

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

Основные, общие, вспомогательные (под)домены

Люди часто путаются, когда слышат, что основной домен на самом деле является поддоменом. В своих книгах по DDD Eric Evans называет их основными доменами, но он также называет их поддоменами. Запутались еще больше?

Если рассматривать домены и поддомены как неявные, а поддомены — как домены, то использование основных доменов и основных поддоменов как взаимозаменяемых не имеет особого значения. Это неявно, но не двусмысленно.

Core Domain (основной домен) звучит лучше, Core Subdomain (основной поддомен) подчеркивает, что существует домен более высокого уровня, куда входит данный объект.

Пространство задач в сравнении с пространством решений: лучшая модель для DDD

Самыми запутанными терминами являются пространство задач и пространство решений. У каждого существует свой взгляд на то, что находится в пространстве задач и в пространстве решений согласно контексту Domain-Driven Design.

Я думаю, что модель пространства задач/решений слишком упрощенная для того, что пытается выразить DDD. Она чересчур неоднозначна и требует большей точности. На мой взгляд, элементы цикла стратегии Simon Wardley гораздо больше подходят для использования.

Domain driven design что это. Смотреть фото Domain driven design что это. Смотреть картинку Domain driven design что это. Картинка про Domain driven design что это. Фото Domain driven design что этоЦикл стратегии Simon Wardley’s

В цикле стратегии Wardley есть следующие элементы (с моими упрощенными определениями):

Цель: какова проблема, которую мы решаем / цель, которая должна быть достигнута в интересующем нас домене?

Среда: каково текущее состояние интересующей нас области (областей).

Климат: что влияет на интересующую нас область и как это может эволюционировать.

Доктрина: мы должны применять хорошие универсальные методы.

Лидерство: каково наше решение. какие изменения мы собираемся внести в существующую и новую область (области).

Являются ли домены/поддомены пространством задач или решений?

На этот вопрос не получится ответить, пока у нас нет четкого определения пространства задач или пространства решений. Но я все равно попробую.

Потребности и проблемы пользователей существуют в (под)домене(ах), текущее состояние имеет (под)домены, решение будет включать несколько (под)доменов и оно изменит состояние среды (которая имеет домены). Поэтому (под)домены логически присутствуют во всех пространствах.

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

Domain driven design что это. Смотреть фото Domain driven design что это. Смотреть картинку Domain driven design что это. Картинка про Domain driven design что это. Фото Domain driven design что это

Мое понимание пространства задач и решений в DDD. Существует множество других определений.

Новые решения создают новые проблемы, или, говоря словами Simon Wardley, Системы Высшего Порядка Создают Новые Источники Дохода.

Я по-прежнему рекомендую избегать использования термина «задача/пространство» и вместо этого уточнять, что вы на самом деле имеете в виду: цель, среда, климат, доктрина, лидерство или что-то еще.

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

Домены иерархичны

Если домен может содержать поддомены, а поддомен — это домен. то поддомен может содержать поддомены, которые меньше. Домены и поддомены — это иерархическая концепция.

При проектировании социотехнических систем мы часто хотим показать домены на разных уровнях. Руководство организации пожелает отобразить 7 доменов верхнего уровня компании. Архитекторы программного обеспечения возможно посчитают необходимым увидеть границы доменов для 100 микросервисов.

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

Domain driven design что это. Смотреть фото Domain driven design что это. Смотреть картинку Domain driven design что это. Картинка про Domain driven design что это. Фото Domain driven design что этоДомены являются иерархическими и представляют бизнес-возможности

Поддомен в сравнении с ограниченным контекстом

Это одна из самых запутанных вещей в DDD, но когда у вас есть четкое определение поддомена, то объяснить его проще всего.

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

Модель в DDD может быть представлена в различных форматах, например, в виде заметок или кода. Все то, что показывает концепции домена, отношения, правила и так далее.

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

Domain driven design что это. Смотреть фото Domain driven design что это. Смотреть картинку Domain driven design что это. Картинка про Domain driven design что это. Фото Domain driven design что это

Поддомены в сравнении с ограниченными контекстами: Области домена в сравнении с границами моделей домена

Согласны или не согласны?

Согласны ли вы с этими определениями и будете ли использовать их в дальнейшем? Если нет, пожалуйста, оставьте комментарий. Я больше забочусь о создании общего понимания в сообществе DDD, чем о продвижении моих определений в качестве стандартов де-факто. Буду очень рад изменить свое мнение.

Всех желающих приглашаем на открытый урок «Почему все начинается с требований?». На занятии разберём, зачем нужны требования к ПО и каких видов они бывают. РЕГИСТРАЦИЯ

Источник

Ценности DDD

Основоположником DDD (Domain Driven Design, предметно-ориентированное проектирование) является Эрик Эванс, который в довольно далеком 2003 году подарил миру свою знаменитую книгу о предметно-ориентированном проектировании. Безусловно, не все, что описано в книге придумал автор с нуля. Многие идеи и практики существовали и до него, но у Эванса получилось все это систематизировать и правильно расставить акцента. Давайте попробуем разобраться, что же именно предлагает Эванс.

На мой субъективный взгляд DDD стоит на трех основных столпах (и это если что не три буквы Д):

Доменная модель

Transaction Script и Domain Model

If all your logic is in services, you’ve robbed yourself blind.

В качестве альтернативы выступает понятие доменной модели. Доменная модель создается, как некое подобие реального мира. Например, если мы разрабатываем ПО для ресторанов и доставки блюд, то наверняка в такой модели нам встретятся такие объекты как: ресторан, блюдо, курьер и может быть, что-то еще при более детальном рассмотрение предметной области.

В отличие от Transaction Script, где логика содержится в сервисах, а данные в сущностях, в доменной модели и логика и данные размещены в доменных объектах. Согласно идеям объектного-программирования такие объекты инкапсулируют свое внутреннее состояние, а для работы с ним предоставляют вполне определенный внешний интерфейс. Например, у объекта корзины может быть метод добавления товара. Тут можно возразить и сказать, что у нашей сущности вполне может быть сеттер для добавления товара.

Да, все это верно. Но не стоит забывать, что в идеале класс корзины должен соблюдать ряд бизнес-инвариантов. Например, после добавления товара в корзину, итоговая стоимость корзины должна увеличится на сумму добавленных товаров. В подходе Transaction Script данная логика размещается в сервисе. Но при таком раскладе соблюдение инвариантов не обеспечивается ничем, кроме хороших тестов и внимательности программиста. Существует не нулевая вероятность, что в каком-то другом сервисе проявится ошибка и он изменит данные корзины неверным образом. В случае же с доменной моделью, за корректность изменения данных (за соблюдение инвариантов) отвечает только один объект сама корзина (может быть еще ее «внутренние классы», но опять же об этом мы не знаем, за счет соблюдения подхода сокрытия информации). Таким образом мы формируем абстракцию корзины, с которой должны взаимодействовать другие классы модели, через ее определенный интерфейс, а не влияя напрямую на ее внутреннее состояние. Также автоматически начинают соблюдаться еще и такие принципы, как SRP (принцип единственной ответственности), low coupling и high cohesion (слабая внешняя связанность и высокое внутреннее зацепление).

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

Единый язык

Единый язык — это некий набор терминов, относящихся к разрабатываемой доменной модели, который использует команда разработки в общение между собой. Важно заметить, что в состав команды входят не только разработчики, но и бизнес-эксперты. Единый язык — это не язык программистов, так же это и не язык бизнес-аналитиков. Единый язык — это своего рода некое смешение, которое возникает в результате совместной работы этих двух категорий специалистов. Это позволяет, как программистам при общении с доменными экспертами более погрузиться в предметную область, так и специалистам предметной области понять, что же все же пытаются создать разработчики (Безусловно, доменные эксперты должны иметь поверхностное представление об объектно-ориентированном моделировании, они не должны впадать в ступор только лишь при упоминании таких слов, как класс и объект). При этом доменные эксперты могут дать обратную связь разработчикам даже до момента написания первой строчки кода. Во время анализа способов использования системы (use cases) разрабатываемой системы, обсуждение, которых должно вестись с активным применением терминов из словаря Единого языка.

DDD — это про общение между людьми, одна из его задач — сломать имеющийся «языковой барьер» между бизнесом и разработкой.

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

Размышляя на тему DDD и хорошо проработанной доменной модели у меня всегда возникает ассоциация с небезызвестным высказыванием:

Сначала ты работаешь на репутацию, а потом она работает на тебя.

Хорошую доменную модель не легко построить, но в какой-то момент окажется, что дальнейшие изменения вносятся, как по маслу. Модель развивается логичным образом, сложность внесения изменений предсказуема, а результат управляем. И в этот момент модель начинает работать уже на тебя.

Ограниченный контекст

Тут уже все несколько посложнее. Есть понятие предметная область, она же и есть домен (domain). Это та сфера деятельности, в которой работает наш бизнес. Например, тот же самый e-commerce, доставка еды из ресторанов, бухгалтерская сфера или что-то иное. В любом случае это весьма обширная сфера и при разработке ПО нет смысла моделировать всю эту огромную область.

Практически всегда в нашей предметной области есть подобласти (subdomain). Подобласти это своего рода отдельно взятые «боли» бизнеса, т.е. это бизнес-проблема, бизнес-задача, которую требуется решить в нашем случае за счет автоматизации. Например, нам может требоваться автоматизация для формирования заказов, для производства товаров, для их доставки. Все это разные подзадачи из одной и той же предметной области. Можно переформулировать иначе. На предприятии могут быть разные подразделения: производство, доставка и служба продаж принимающая заказы и наша цель состоит в разработке ПО для данных подразделений предприятия.

Разное использование понятий в зависимости от контекста

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

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

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

Области задач и области решений

Вон Вернон рассматривает субдомены, как области бизнес-задач, а ограниченные контексты, как области решений.

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

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

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

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

Ограниченный контекст как способ декомпозиции системы

Идея ограниченного контекста это своего рода желание декомпозировать большую систему на более простые компоненты, с которыми понятней и более удобно работать. Также можно сказать, что данная идея реализует все те же принципы проектирования SRP, low coupling и high cohesion, но только на более высоком уровне. Об этом также говорит принцип CCP (Common Closure Principle), который похож на SRP, но только для классов, изменяющимся по одной и той же причине и следовательно должны находится вместе, например, в одном пакете. Также эта идея отлично согласуется с другими подходами, например, с микро сервисной архитектурой и с гибкими командами в Agile.

Закон Конвея

Организации проектируют системы, которые копируют структуру коммуникаций в этой организации

Даже когда я приводил пример с подразделениями организации, то невольно рассматривалась декомпозиция системы по бизнес-возможностям предприятия, которые уже структурированы определенным образом. Что на мой взгляд перекликается с законом Конвея.

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

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

Агрегаты

Если ранее по большей мере речь шла о так называемых стратегических шаблонах DDD, то сейчас хочется сказать пару слов в самом интересном на мой взгляд тактическом шаблоне, об Агрегате.

Приходилось ли вам в коде видеть что-то подобное?

Данный код представляет своего рода довольно глубокий обход графа объектов нашей предметной модели. В нашей модели имеются несколько объектов-сущностей: Payment, Order, Account, Client И Address. И все эти объекты имеют некоторые связи друг с другом. B это довольно знакомая и распространенная ситуация. И само собой такая тесная связь между объектами вызывает и большую связанность самого кода. И это даже не говоря о том, что такая связь может быть не всегда обязательной и тем самым, подобный невнимательный обход объектов может вызывать исключение NullPointerException.

Подход DDD предлагает разбить большой граф объектов всего приложения на слабосвязанные агрегаты, которые представляют собой совокупность тесно связанных объектов. Агрегаты не используют ссылочное связывание объектов. Вместо этого модель осуществляет взаимодействие агрегатов по идентификаторам. Внутри агрегата объекты могут связываться друг с другом по ссылке. Агрегат инкапсулирует все свои внутренние объекты и предоставляет интерфейс для работы с ним. Модель должна использовать только этот интерфейс, но не взаимодействовать с внутренними объектами агрегата напрямую.

Агрегат как граница транзакционной согласованности

Когда говорят про агрегаты не редко упоминают транзакционную согласованность этих агрегированных объектов. Например, в качестве агрегата, можно рассмотреть корзину товаров. Корзина помимо своих основных свойств таких, как подытог, скидка и итоговая сумма содержит такие объекты как CartItem. Данный объект представляет элемент корзины и может содержать такие свойства, как добавленный товар и его количество, а также может вычислять подытог, как произведение количества на стоимость товара. Агрегат корзина (как и любой доменный объект) обеспечивает необходимые бизнес-инварианты (например, пересчет стоимости при добавление еще одного товара). Также очевидно, что при сохранении корзины должны одновременно сохраняться и ее элементы в рамках одной транзакции, что удовлетворяет транзакционной согласованности.

По этому при проектировании агрегата всегда можно задаться вопросом:

А должны ли эти объекты сохраняться вместе?

Агрегаты и границы ограниченных контекстов

Агрегаты — это тот инструмент, который помогает разделить модель на слабосвязанные ограниченные контексты.

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

Агрегаты и событийно-ориентированный архитектура

DDD уменьшает связанность за счет использования Агрегатов. Но агрегаты, как и любые объекты должны взаимодействовать друг с другом. В DDD это взаимодействие осуществляется за счет публикации событий. В ходе жизненного цикла и изменение своего состояния агрегат может генерировать различные события, которые могут быть приняты и обработаны в другой части модели. Событийно-ориентированный подход также помогает снизить связность системы. Использование событий также можно рассматривать, как способ приведения распределенной системы к конечному согласованному состоянию.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *