25 июля 2021

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 3)

Backend Java Developer
Domain Driven Design дает большие возможности по созданию крупных проектов, которые в будущем становятся надежными и легко масштабируемыми. Как пройти полный проектный цикл, от бизнес-модели до AWS?
☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 3)
Первая и вторая части серии были посвящены подготовительному этапу. На примере минималистического проекта Spring Boot мы проверили полный цикл работ и выставили приложение на AWS. В этой статье мы начинаем второй этап, архитектурный. Нам придётся пробежаться по теории предметно-ориентированного проектирования (Domain-Driven Design или DDD). Надо будет разобраться с предметной областью, ограниченными контекстами, моделями и сервисами предметной области. Также проведём проектирование, в нашем случае это будет экстренная медицинская помощь, где мы применим DDD при моделировании архитектуры.

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

Основные определения

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

DDD – это борьба со сложностью бизнес-логики.

DDD состоит из…

- архитектурной части (стратегическое моделирование):

  • единый язык;
  • предметная область;
  • предметная подобласть (или ограниченный контекст в частном случае);
  • смысловое ядро;
  • ограниченный контекст;
  • карта контекстов.

- реализационной части (тактическое моделирование):

  • сущность (определенное понятие предметной области, уникальное, отличительный от других объектов в системе своей идентичностью);
  • объект-значение (персистентный объект в предметной области, без своей идентичности);
  • службы предметной области;
  • события;
  • модули;
  • агрегаты.

В чем преимущество DDD?

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

Начните со стратегического моделирования:

  • определите задачи основной предметной области (бизнес-домена);
  • разделите предметную область на поддомены, ограниченные контексты (бизнес-функции);

Затем, переходите к тактическому моделированию:

  • для определения модели предметной области ограниченного контекста, идентифицируйте агрегаты, операции, процессы и потоки.

Давайте проясним основные понятия архитектурной и реализационной частей.

Архитектурная часть

Знание предметной области (Domain Knowledge)

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

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

Единый язык (The Ubiquitous Language)

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

Предметная область (Problem Space)

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

Поддомены (SubDomain), ограниченные контексты (Bounded Context)

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

☕ Подтянуть свои знания по Java вы можете на нашем телеграм-канале «Библиотека Java для собеса»

Реализационная часть

Модель предметной области (Domain Model)

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

  • бизнес-сущность (сущность, объект-значение, агрегат);
  • бизнес-правило (правило предметной области);
  • бизнес-поток (менеджер событий, долговременные транзакции, сага);
  • бизнес-операция (команда, запрос);
  • бизнес-событие (событие).
Соотнесение бизнес-языка и технического языка
Соотнесение бизнес-языка и технического языка

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

***
Проект: «Экстренная медицинская помощь»

Пользовательские истории (User Experience, UX)

Основные определения

  • Дистанционное предоставление медицинских услуг, телемедицина.
  • Служба экстренной медицинской помощи.
  • Средства телекоммуникации – компьютер, мобильное устройство, Интернет.

Сценарий действий, как это будет происходить

Первичная регистрация пациента:

  1. Регистрируется в системе (устанавливает приложение на свой компьютер или на мобильное устройство).
  2. Заносит необходимые данные о себе.
  3. Сервер регистрирует информацию о пациенте.

Рабочий процесс:

  1. При экстренной ситуации пациент делает вызов, передает информацию о своем здоровье.
  2. Информация может передаваться текстовым, голосовым и видео-файлом.
  3. Информация анализируется и в зависимости от экстренной ситуации назначается лечащий врач.
  4. Врач анализирует информацию и принимает меры. В зависимости от степени чрезвычайности ситуации, дистанционно консультирует и оказывает медицинскую помощь пациенту, а в случае необходимости организует вызов бригады скорой/неотложной помощи.
  5. Вся информация автоматически записывается и архивируются.

Конечно, со стороны заказчика может быть предложен расширенный вариант UX. В нашем вымышленном проекте достаточно и этой информации.

🧩☕ Интересные задачи по Java для практики можно найти на нашем телеграм-канале «Библиотека задач по Java»

Строим архитектуру проекта

Определяем основную предметную область – это дистанционная экстренная медицинская помощь пациенту.

Определяем артефакты основной предметной области – у нас будут следующие артефакты:

  • поддомены (ограниченные контексты);
  • модель предметной области и операции модели предметной области;
  • саги предметной области (долговременные транзакции);
  • сервисы модели предметной области.

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

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

Разделяем основную предметную область на поддомены
Разделяем основную предметную область на поддомены

Определяем несколько ограниченных контекстов.

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 3)

В нашем случае, контексты, это:

вызов (recourse)

Эта область включает обращение пациента в службу экстренной помощи, а также следующие операции:

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

диагностика (diagnosis)

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

  • получение предварительных данных по пациенту из реестра архива экстренной службы;
  • получение предварительных данных по пациенту из других/внешних источников;
  • анализ полученных данных на основании обращения пациента.

лечение (treatment)

Эта область включает в себя процесс лечения пациента, а также следующие операции:

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

отслеживание (tracking)

Эта область включает в себя процесс оказания экстренной помощи пациенту, а также следующие операции:

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

Давайте установим правила проектирования для нашего приложения.

в отношении ограниченных контекстов:

  1. ограниченный контекст – это один поддомен;
  2. замена интерфейсов на идентификаторы;
  3. контексты общаются через API и разделены через сервисы;
  4. размещение ограниченного контекста на микросервис, или же
  5. размещение агрегата на микросервис, или же
  6. размещение агрегата на несколько физических микросервисов.

для связи микросервисов:

  • связи между агрегатами через идентификатор;
  • связь с внешними сервисами через миграцию данных;

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

Бизнес-область Ограниченный контекст
вызов (recourse) Вызов (recourse)
диагностика (diagnostics) Диагноз (diagnose)
лечение (treatment) Лечение (treatment)
отслеживание (tracking) Отслеживание (tracking)

Определим модель предметной области

У нас будет два основных набора артефактов для модели предметной области.

- для модели основной предметной области:

  • агрегаты;
  • идентификаторы агрегатов;
  • сущности;
  • объекты-значения.

- для операций модели предметной области:

  • команды (изменяют состояние в ограниченном контексте);
  • запросы (запрашивают состояние ограниченного контекста);
  • события (сообщают об изменении состояния ограниченного контекста).

Давайте, разберемся со всеми по порядку

Агрегаты (Aggregates) в ограниченном контексте

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

  • корневую сущность (Root Entity);
  • набор объектов-сущностей (Entity Objects);
  • набор объектов-значений (Value Objects).

Идентификаторы агрегатов

Каждый агрегат должен быть обозначен идентификатором агрегата (Aggregate Identifier) и реализуется при помощи бизнес-ключа (Business Key).

  • вызов (recourse) Вызов (RecourseId);
  • диагностика (diagnosis) Диагноз (DiagnoseId);
  • лечение (treatment) Лечение (TreatmentId);
  • отслеживание (tracking) – Отслеживание (TrackingId).

Сущности (Entities)

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

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 3)

Определяем сущности в наших агрегатах.

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 3)

Объекты-значения (Value-Objects)

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

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 3)

Команды (Commands)

Это операции, которые требуют изменения состояния в ограниченном контексте.

Запросы (Queries)

Это операции, которые запрашивают состояние ограниченного контекста.

События (Events)

сообщают об изменении состояния ограниченного контекста.

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 3)
Команды, запросы, события
Команды, запросы, события

Саги (Sagas)

В распределенных системах на основе микросервисов реализуется механизм поддержания логической целостности данных при взаимодействии нескольких микросервисов. Саги реализуют это методом хореографии (Event Choreography) или оркестровки событий (Event Orchestration). Сага позволяет приложению поддерживать согласованность данных между сервисами без использования распределенных транзакций.

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 3)

Определяем сервисы модели предметной области

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

  • взаимодействует с внешней средой посредством интерфейсов;
  • взаимодействует с другими ограниченными контекстами;
  • публикует события об изменениях своего состояния во внешних брокерах сообщений;
  • взаимодействует с внешними источниками для сохранения состояния в хранилищах данных;

Существует три типа сервисов модели предметной области для ограниченного контекста:

  1. входящие сервисы (внешнее взаимодействие с моделью предметной области);
  2. исходящие сервисы (взаимодействие модели предметной области с внешними репозиториями и ограниченными контекстами);
  3. сервисы приложения (унифицированный интерфейс между моделью предметной области и входящими/исходящими сервисами).
Сервисы предметной области
Сервисы предметной области

Резюме

Мы вкратце прошлись по DDD применительно к вымышленному проекту экстренной медицинской помощи. Были даны определения для ограниченных контекстов, агрегатов, модели предметной области и других понятий, необходимых при предметно-ориентированном проектировании.

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

МЕРОПРИЯТИЯ

Комментарии

ВАКАНСИИ

Добавить вакансию
Senior Java Developer
Москва, по итогам собеседования
Java Team Lead
Москва, по итогам собеседования

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ