"Application Architecture for a Backend with Rich Business Logic – How to Ensure Maintainability?", Andrii Riabets.pptx

fwdays 36 views 46 slides Sep 22, 2025
Slide 1
Slide 1 of 46
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27
Slide 28
28
Slide 29
29
Slide 30
30
Slide 31
31
Slide 32
32
Slide 33
33
Slide 34
34
Slide 35
35
Slide 36
36
Slide 37
37
Slide 38
38
Slide 39
39
Slide 40
40
Slide 41
41
Slide 42
42
Slide 43
43
Slide 44
44
Slide 45
45
Slide 46
46

About This Presentation

This presentation will focus on the maintainability quality attribute — how to keep business logic isolated, consolidated, encapsulated, and consistent, as well as how to integrate it with the infrastructure layer, including persistence, messaging etc.
All these aspects will be illustrated through...


Slide Content

Backend with rich business logic - how to ensure Maintainability Автор: Андрій Рябець

Про що поговоримо?

Про що поговоримо?

Тематика

Infrastructure Performance Security Business logic Частка логіки в об’ємі робіт

Фокус

Складність читання і розуміння коду 1 Maintainability Складність/швидкість внесення змін 2 Ймовірність допустити помилку 3

Засоби досягнення

Інгредієнти

Uklon Контекст

Трилема DDD

ПОВНОТА 1 Обрані пріоритети КОНСИСТЕНТНІСТЬ ТА ІНКАПСУЛЯЦІЯ 2 ЧИСТОТА 3

Архітектура

IStorage - Unit Of Work трекає опубліковані доменні івенти зберігає агрегати конвертує агрегати в query model-і зберігає query model-і публікує підмножину доменних івентів назовні контексту, конвертуючи їх в інтеграційні

Persistence Command model - document-oriented approach in RDBMS природно лягає в концепцію агрегатів DDD тривіальне використання ORM природна одиниця для вирішення concurrency -конфліктів через optimistic strategy ACID доменна модель конвертується в окрему DAL-модель (гнучкіше - зміна моделі без міграції, обмеження ORM etc.) Query model - адаптовані read-проекції під необхідні запити Single transaction - агрегат та query model зберігаються в одній БД в рамках однієї транзакції дозволяє використовувати query model в command-сценаріях

Збереження Command Model

Конвертація в Query Model

Як досягти на прикладі реальної задачі - реєстрація приватного водія

Заявка на реєстрацію

Модель приватного водія

МОДЕЛЬ ПРИВАТНОГО ВОДІЯ Модель загалом складається з 4-ьох агрегатів : з користувача, який може виступати в кількох ролях з водія, який ідентифікується по номеру водійського посвідчення і може працювати в різних автопарках з авто, яке ідентифікується по держ номеру і VIN-коду та може переходити з парку в парк і врешті з автопарку, який має власника, водіїв-співробітників (з датами співробітництва) та автомобілів з періодом перебування в парку Приватний водій - частковий випадок автопарку з одним водієм, який одночасно є його власником, та одним авто

Use case-и на AppService

Логіка в агрегаті

Логіка в агрегаті

Інкапсуляція доменних івентів

Псевдохореографія

Псевдохореографія

Явна оркестрація

Підписка на доменні івенти

Інкапсуляція internal-методу

Декларація зовнішнього івенту

Реалізація на AppService-layer

Конвертація зовнішнього в доменний

Обробка в домені

Організація коду

ПІДСУМКИ

ПОВНОТА валідація (навіть проста по типу номера тел чи email) - теж бізнес-логіка авторизація - теж бізнес-логіка query -інг даних для перевірок та прийняття рішень - теж бізнес-логіка Виключення : реалізація методів в SpecificRepository -іях - логіка виконання запитів винесена в IStorage-адаптер

Інкапсуляція та консистентність валідація простих типів даних -в фабричних методах value object -ів здійснюємо авторизацію використання ReadOnly-колекцій в public -пропертях з інкапсуляцією модифікабельної колекції в полі не створюємо “дірок” для обходу інваріанту Domain Events має мати можливість створювати (і як наслідок - публікувати ) тільки сам агрегат-власник івента передачу управління по flow між агрегатами робимо за допомогою доменних івентів у випадку decoupled частин у flow якщо по доменному івенту має запуститись складний процес за участі кількох агрегатів, який потребує оркестрації: виділити явний доменний сервіс , який консолідує і зробить observable процес оркестрації відкрити методи, необхідні для цього оркестратора, тільки йому

Контрольовані порушення інкапсуляції public -метод static RestoreState для відновлення стану агрегату зі сховища методи встановлення контексту AppUser.SetCurrent(xxx) - встановлюється один раз при ініціалізації обробки запитів/повідомлень, по необхідності в юніт-тестах Publisher.SetInstance(xxx) - встановлюється один раз в контексті Unit Of Work, по необхідності в юніт-тестах public IIncomeExternalEvent : IDomainEvent - реалізувати інтерфейс і опублікувати івент може хто завгодно

Компроміси в ЧИСТОТІ для повноти IReadOnlyStorage для можливості query-інга даних з домену async/await в домені

Q&A