Зачем UML в System Design
Из 14 типов UML-диаграмм для System Design достаточно трёх: Sequence, Class и Activity. Они покрывают основные потребности: взаимодействие компонентов, структура данных и бизнес-логика.
Три столпа UML для архитектора
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Sequence │ │ Class │ │ Activity │
│ Diagram │ │ Diagram │ │ Diagram │
│ │ │ │ │ │
│ КАК компоненты │ │ ИЗ ЧЕГО │ │ КАК работает │
│ общаются │ │ состоит │ │ процесс │
│ (взаимодействие)│ │ (структура) │ │ (поведение) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
Sequence Diagrams
Sequence diagram показывает обмен сообщениями между участниками во времени.
Основные элементы
| Элемент | Обозначение | Описание |
|---|---|---|
| Участник (Actor) | Прямоугольник наверху | Объект, сервис, пользователь |
| Lifeline | Вертикальная линия | Время жизни участника |
| Синхронный вызов | ──▶ (сплошная стрелка) | Вызов с ожиданием ответа |
| Асинхронный вызов | ──> (пунктирная стрелка) | Вызов без ожидания |
| Ответ | ◁── (пунктирная обратная) | Возврат результата |
| Самовызов | Петля на себя | Внутренняя обработка |
| Alt/Opt/Loop | Рамка с условием | Условия и циклы |
Пример: Авторизация пользователя
Client API Gateway Auth Service Database Redis
│ │ │ │ │
│ POST /login │ │ │ │
│────────────────▶│ │ │ │
│ │ Validate │ │ │
│ │ credentials │ │ │
│ │───────────────▶│ │ │
│ │ │ SELECT user │ │
│ │ │──────────────▶│ │
│ │ │ user data │ │
│ │ │◁─────────────│ │
│ │ │ │ │
│ │ │──┐ Verify │ │
│ │ │ │ password │ │
│ │ │◁─┘ │ │
│ │ │ │ │
│ │ │──┐ Generate │ │
│ │ │ │ JWT token │ │
│ │ │◁─┘ │ │
│ │ │ │ │
│ │ │ Store session│ │
│ │ │─────────────────────────────▶│
│ │ │ OK │
│ │ │◁────────────────────────────│
│ │ │ │ │
│ │ JWT token │ │ │
│ │◁──────────────│ │ │
│ 200 + JWT │ │ │ │
│◁───────────────│ │ │ │
Alt (условие)
Client Order Service Payment Service
│ │ │
│ Create Order │ │
│─────────────────────▶│ │
│ │ Process Payment │
│ │──────────────────────▶│
│ │ Payment Result │
│ │◁─────────────────────│
│ │ │
│ ┌────────────────────────┐ │
│ │ ALT [payment success] │ │
│ │ │ │ │
│ │ │──┐ Create order │ │
│ │ │ │ in DB │ │
│ │ │◁─┘ │ │
│ 201 Created │ │ │ │
│◁────────────────│ │ │ │
│ ├────────────────────────┤ │
│ │ [payment failed] │ │
│ │ │ │ │
│ 402 Payment │ │ │ │
│ Required │ │ │ │
│◁────────────────│ │ │ │
│ └────────────────────────┘ │
Паттерны Sequence Diagrams
| Паттерн | Описание | Когда |
|---|---|---|
| Request-Response | Синхронный вызов + ответ | REST API |
| Fire-and-Forget | Асинхронный вызов без ответа | Отправка в очередь |
| Callback | Ответ приходит позже через другой канал | Webhooks |
| Saga | Цепочка компенсирующих транзакций | Distributed transactions |
Class Diagrams
Class diagram показывает структуру: классы, атрибуты, методы и связи между ними.
Основные элементы
┌──────────────────────────────┐
│ <<interface>> │ ← Стереотип
│ Repository │ ← Имя класса
├──────────────────────────────┤
│ │ ← Атрибуты (пусто для interface)
├──────────────────────────────┤
│ + FindByID(id: UUID): Entity │ ← Методы
│ + Save(entity: Entity): void │
│ + Delete(id: UUID): void │
└──────────────────────────────┘
Модификаторы доступа:
+ public # protected - private ~ package
Типы связей
Ассоциация (использует):
[Order] ──────────▶ [Customer]
"Order имеет ссылку на Customer"
Агрегация (содержит, может существовать отдельно):
[Department] ◇─────▶ [Employee]
"Department содержит Employee, но Employee может существовать без Department"
Композиция (владеет, не может существовать отдельно):
[Order] ◆─────▶ [OrderItem]
"OrderItem не может существовать без Order"
Наследование (является):
[Cat] ──────────▷ [Animal]
"Cat является Animal"
Реализация (реализует интерфейс):
[PostgresRepo] ──────▷ [Repository]
"PostgresRepo реализует Repository"
Зависимость (использует временно):
[OrderService] ┄ ┄ ┄ ▶ [EmailSender]
"OrderService использует EmailSender"
Пример: Domain Model интернет-магазина
┌──────────────────┐ ┌──────────────────┐
│ User │ │ <<enum>> │
├──────────────────┤ │ OrderStatus │
│ - id: UUID │ ├──────────────────┤
│ - email: string │ │ PENDING │
│ - name: string │ │ PAID │
├──────────────────┤ │ SHIPPED │
│ + Register() │ │ DELIVERED │
│ + Authenticate() │ │ CANCELLED │
└────────┬─────────┘ └──────────────────┘
│ 1 ▲
│ │ uses
│ has many │
▼ * │
┌──────────────────┐ ┌───────┴──────────┐
│ Order │ │ OrderItem │
├──────────────────┤ ├──────────────────┤
│ - id: UUID │ 1 * │ - productId: UUID│
│ - status: Status │◆─────▶│ - quantity: int │
│ - total: Money │ │ - price: Money │
│ - createdAt: Time│ ├──────────────────┤
├──────────────────┤ │ + Subtotal() │
│ + AddItem() │ └──────────────────┘
│ + Submit() │
│ + Cancel() │
└──────────────────┘
Мультипликаторы (Multiplicity)
| Обозначение | Значение |
|---|---|
| 1 | Ровно один |
| 0..1 | Ноль или один |
| * | Ноль или много |
| 1..* | Один или много |
| 3..5 | От трёх до пяти |
Activity Diagrams
Activity diagram показывает поток выполнения: шаги, условия, параллельные ветки.
Основные элементы
| Элемент | Символ | Описание |
|---|---|---|
| Start | (●) | Начальный узел |
| End | (◉) | Конечный узел |
| Action | [прямоугольник] | Действие |
| Decision | ◇ | Условие (ветвление) |
| Merge | ◇ | Объединение веток |
| Fork | ═══ | Начало параллельного выполнения |
| Join | ═══ | Ожидание всех параллельных веток |
| Swimlane | Вертикальная полоса | Ответственный за действие |
Пример: Обработка заказа
(●) Start
│
▼
[Получить заказ]
│
▼
◇ Товар в наличии?
/ \
Да Нет
│ │
▼ ▼
│ [Уведомить клиента]
│ │
│ ▼
│ (◉) End
│
▼
═══════════════════ (Fork: параллельно)
│ │
▼ ▼
[Списать оплату] [Зарезервировать
│ товар на складе]
│ │
▼ ▼
═══════════════════ (Join: ждём обе ветки)
│
▼
[Создать отправку]
│
▼
[Отправить уведомление
клиенту]
│
▼
(◉) End
Пример: Saga паттерн
(●) Start
│
▼
[Create Order]
│
▼
[Reserve Inventory] ──── Fail ───▶ [Cancel Order] ──▶ (◉)
│
│ Success
▼
[Process Payment] ──── Fail ───▶ [Release Inventory]
│ │
│ Success ▼
▼ [Cancel Order] ──▶ (◉)
[Confirm Order]
│
▼
[Send Notification]
│
▼
(◉) End
PlantUML для UML-диаграмм
PlantUML позволяет описывать UML-диаграммы текстом.
Sequence Diagram в PlantUML
@startuml
actor Client
participant "API Gateway" as GW
participant "Auth Service" as Auth
database "PostgreSQL" as DB
Client -> GW: POST /login
GW -> Auth: Validate credentials
Auth -> DB: SELECT user
DB --> Auth: user data
Auth -> Auth: Verify password
Auth -> Auth: Generate JWT
Auth --> GW: JWT token
GW --> Client: 200 + JWT
@enduml
Class Diagram в PlantUML
@startuml
class Order {
-id: UUID
-status: OrderStatus
-total: Money
+AddItem(item: OrderItem)
+Submit(): void
+Cancel(): void
}
class OrderItem {
-productId: UUID
-quantity: int
-price: Money
+Subtotal(): Money
}
Order "1" *-- "*" OrderItem : contains
@enduml
Когда какую диаграмму
| Ситуация | Диаграмма | Пример |
|---|---|---|
| Как сервисы общаются при запросе | Sequence | Авторизация, оформление заказа |
| Структура доменной модели | Class | Entity, Value Objects, Aggregates |
| Бизнес-процесс с условиями | Activity | Обработка заказа, модерация |
| Состояния объекта | State Machine | Жизненный цикл заказа |
| Общая архитектура | C4 (не UML) | Контейнеры, компоненты |
Итоги
| Диаграмма | Отвечает на вопрос | Ключевые элементы |
|---|---|---|
| Sequence | Как компоненты общаются? | Участники, сообщения, время |
| Class | Из чего состоит? | Классы, атрибуты, связи |
| Activity | Как работает процесс? | Действия, условия, параллельность |
Главное правило: UML -- инструмент коммуникации, а не документирования ради документирования. Рисуй диаграмму, когда она помогает объяснить идею, и не рисуй, когда код говорит сам за себя.