Skip to content

Створення проєкту за архітектурою "Порти та адаптери"

Мета: Ознайомитися з принципами архітектури "Порти та адаптери" (Hexagonal Architecture). Навчитися розділяти бізнес-логіку та взаємодію із зовнішніми системами через інтерфейси.


Завдання

  • 1. Підготовка до EventStorming
    1. Визначити предметну область для моделювання (наприклад, система бронювання готелів або інтернет-магазин).
    2. Підготувати інструменти для роботи (стікери, маркери, дошку або онлайн-інструмент, наприклад, Miro, Mural).
    3. Визначити учасників процесу (замовник, бізнес-аналітики, розробники тощо).
  • 2. Проведення EventStorming-сесії
    1. Записати ключові події бізнес-процесу у формі «Що сталося?» (наприклад, Замовлення оформлене, Оплата підтверджена).
    2. Додати акторів, які ініціюють події (наприклад, Клієнт, Менеджер,** Система платежів**).
    3. Додати агрегати (сутності, які зберігають стан, наприклад, Замовлення, Кошик).
    4. Визначити команди (що потрібно зробити, щоб подія відбулася, наприклад, Підтвердити оплату, Зареєструвати користувача).
  • 3. Аналіз отриманої моделі
    1. Виділити основні bounded contexts (області відповідальності системи).
    2. Виявити потенційні інваріанти (правила, які не можна порушувати).
    3. Визначити зовнішні інтеграції (API, сервіси, зовнішні системи).
    4. Перевірити у**згодженість подій** і логіку процесу.
  • 4. Документування та підготовка до реалізації
    1. Оформити результати у вигляді діаграми або текстового опису.
    2. Виділити потенційні модулі або мікросервіси для реалізації.

Хід роботи

EventStorming — це візуальна фасилітаційна техніка, розроблена Альберто Брандоліні, яка дозволяє швидко дослідити складну предметну область та створити спільне розуміння бізнес-процесів між технічними спеціалістами та експертами з бізнесу.


1. Підготовка до EventStorming

Крок 1.1: Визначити предметну область для моделювання

Для нашого практичного завдання ми обираємо систему Інтернет-магазину (e-commerce). Ця предметна область містить класичні процеси: вибір товару, оформлення замовлення, оплата та доставка.

Крок 1.2: Підготувати інструменти для роботи

EventStorming можна проводити як офлайн, так і онлайн.

  • Для офлайн-сесії: знадобиться велика стіна або рулон паперу (мінімум 5-8 метрів), багато маркерів та стікери різних кольорів (колір має чітке значення). Треба прибрати стільці, щоб учасники активно переміщалися.
  • Для онлайн-сесії: використовуються віртуальні дошки з безмежним простором, такі як Miro або Mural, зі заздалегідь підготовленими шаблонами та легендою кольорів.

Крок 1.3: Визначити учасників процесу

Для успішного моделювання потрібні люди з різним бекграундом: ті, хто знає відповіді (експерти предметної області, замовники, product owners), і ті, хто ставить запитання (розробники, бізнес-аналітики, тестувальники). Оптимальна кількість учасників — від 5 до 10-12 осіб, щоб кожен міг зробити свій внесок.


2. Проведення EventStorming-сесії

У цій фазі учасники переносять свої знання про систему на дошку, використовуючи спеціальну кольорову граматику: Актор -> Команда -> Агрегат -> Подія -> Політика -> Зовнішня система.

2.4. Записати ключові події (Domain Events) Всі учасники беруть оранжеві стікери і записують значущі бізнес-події. Події завжди формулюються у минулому часі. Приклади для інтернет-магазину: Товар додано до кошика, Замовлення оформлене, Оплату підтверджено, Товар відправлено. Вони розміщуються на дошці в хронологічному порядку.

2.5. Додати акторів (Actors) На світло-жовтих стікерах позначаються користувачі (люди або ролі), які ініціюють дії. Приклади: Клієнт, Менеджер магазину, Адміністратор.

2.6. Додати агрегати (Aggregates) На великих жовтих стікерах визначаються агрегати (сутності в термінах Domain-Driven Design), які зберігають стан системи, приймають команди та генерують події. Приклади: Кошик, Замовлення, Платіж.

2.7. Визначити команди (Commands) На синіх стікерах описуються наміри або дії, які потрібно виконати, щоб подія відбулася. Формулюються у наказовому способі. Приклади: Додати товар, Оформити замовлення, Підтвердити оплату.

Візуалізація ланцюжка подій (Mermaid)

Нижче наведено базовий ланцюжок дій оформлення замовлення, зібраний на EventStorming-дошці.

graph LR
    classDef actor fill:#FFF2CC,stroke:#333,stroke-width:2px;
    classDef command fill:#99CCFF,stroke:#333,stroke-width:2px;
    classDef aggregate fill:#FFD966,stroke:#333,stroke-width:2px;
    classDef event fill:#F6B26B,stroke:#333,stroke-width:2px;
    classDef system fill:#F4CCCC,stroke:#333,stroke-width:2px;
    classDef policy fill:#D9D2E9,stroke:#333,stroke-width:2px;

    A1(👤 Клієнт):::actor --> C1[🟦 Оформити замовлення]:::command
    C1 --> Ag1{🟨 Замовлення}:::aggregate
    Ag1 --> E1((🟧 Замовлення оформлене)):::event

    E1 -.-> P1>🟪 Політика: Коли замовлення оформлене, ініціювати оплату]:::policy
    P1 --> C2[🟦 Провести платіж]:::command

    C2 --> Sys1[[Рожевий: Система платежів Stripe]]:::system
    Sys1 --> E2((🟧 Оплату підтверджено)):::event

3. Аналіз отриманої моделі

Після створення "великої картини" (Big Picture) необхідно проаналізувати логіку та межі системи.

3.8. Виділити основні bounded contexts (області відповідальності) Скупчення пов'язаних агрегатів та подій утворюють Bounded Contexts (обмежені контексти). Це логічні межі, де терміни мають однозначне значення. Для інтернет-магазину це можуть бути: 1. Контекст Каталогу 2. Контекст Замовлень 3. Контекст Оплати 4. Контекст Доставки

3.9. Виявити потенційні інваріанти Інваріанти — це бізнес-правила, які завжди повинні бути істинними протягом усього життєвого циклу агрегату. Приклади: "Замовлення не може містити нуль товарів", "Неможливо оплатити скасоване замовлення".

3.10. Визначити зовнішні інтеграції На рожевих стікерах позначаються зовнішні системи або API, які ми не контролюємо. Вони можуть приймати команди або надсилати події. Приклади: Платіжний шлюз (Stripe/LiqPay), CRM-система, Сервіс відправки Email (SendGrid).

3.11. Перевірити узгодженість подій і логіку процесу Виконується "зворотний прохід" (Reverse narrative) по таймлайну: від кінця до початку. Наприклад, щоб відбулася подія Замовлення відправлено, чи була подія Оплата отримана? Це допомагає знайти пропущені кроки. Будь-які сумніви, ризики або вузькі місця відзначаються червоними (або пурпурними) стікерами Hot Spots.

Виявлення ризиків (Hot Spots)

Якщо експерти не можуть дійти згоди щодо того, як саме розраховується вартість доставки, на це місце клеїться червоний стікер з питанням "Як визначається податок/доставка?". Це завдання для подальшого з'ясування.


4. Документування та підготовка до реалізації

Крок 4.12: Оформити результати у вигляді діаграми

Результати сесії часто фіксуються за допомогою фотографій дошки (для офлайн) або експортуються з Miro у формати зображень та текстів. Отримані моделі трансформуються в UML або архітектурні схеми.

На цьому етапі архітектура розкладається на піддомени (Decompose by Subdomain), що є ідеальною основою для мікросервісної або модульної архітектури.

4.13. Виділити потенційні модулі або мікросервіси для реалізації Кожен виділений Bounded Context (Обмежений контекст) є потенційним кандидатом на окремий мікросервіс або модуль у моноліті (Модульний моноліт). Це гарантує, що сервіси будуть розділені за бізнес-змістом, а не за технічними шарами, що запобігає створенню "розподіленого моноліту".

Карта контекстів та мікросервісів (Context Map)

flowchart TD
    subgraph MS1 [Мікросервіс 'Каталог']
        A1(Агрегат: Товар)
    end

    subgraph MS2 [Мікросервіс 'Замовлення']
        A2(Агрегат: Кошик)
        A3(Агрегат: Замовлення)
    end

    subgraph MS3 [Мікросервіс 'Оплата']
        A4(Агрегат: Платіж)
    end

    subgraph MS4 [Мікросервіс 'Доставка']
        A5(Агрегат: Відправлення)
    end

    Ext1[[API: Платіжний шлюз]]
    Ext2[[API: Логістична компанія]]

    MS1 -- "Товар додано" --> MS2
    MS2 -- "Очікує оплати" --> MS3
    MS3 -- "REST / Запит на списання" --> Ext1
    Ext1 -- "Оплату підтверджено" --> MS3
    MS3 -- "Оплачено" --> MS4
    MS4 -- "REST / Створити ТТН" --> Ext2

Застосування EventStorming таким чином дозволяє зекономити місяці аналізу, сформувати спільну мову (Ubiquitous Language) для всієї команди та підготувати точне підґрунтя для проектування коду за принципами гексагональної архітектури чи чистого DDD.