Взрывная C4 диаграмма
Взрывная C4-диаграмма
Материал этого поста вырос из лекции для участников Студенческой ИТ-Лаборатории.
Тема лекции звучала просто, но на практике оказывается неудобной: как объяснить архитектуру своего проекта так, чтобы её поняли и менеджер, и джун, и тимлид, причём не рисуя один и тот же чертёж для всех троих. Ответ на этот вопрос простой: C4-диаграмма. У неё четыре уровня абстракции, и дальше пойдёт речь о том, что это такое, зачем она нужна, какими инструментами её рисовать и как сделать свою первую диаграмму на практике.
Что такое C4 и зачем она нужна
C4-диаграмма: способ визуализации архитектуры программного обеспечения через четыре уровня абстракции: Context, Containers, Components и Code. Идея в том, чтобы не пытаться уместить всю систему в одну схему, а показывать её слоями, от общей картины до конкретных классов в коде.
Главная задача диаграммы в том, чтобы быстро и понятно объяснить архитектуру ПО всей команде и бизнесу. В рамках лаборатории она решает конкретную практическую задачу: помогает участнику лучше понять архитектурное решение собственного проекта, причём настолько, чтобы его понимали и руководитель отдела, и команда разработки.
Четыре уровня абстракции
Каждый уровень C4 не альтернативный способ нарисовать систему, а её декомпозиция: приближение камеры к предыдущему уровню.
Context
Уровень Context показывает верхнеуровневую схему системы целиком. На нём изображена сама система как единый объект, типы её пользователей и внешние интеграции, с которыми она взаимодействует. Цель уровня в том, чтобы показать границы системы и её окружение. Вопрос, на который он отвечает: кто пользуется системой и с чем она взаимодействует?
Containers
Уровень Containers декомпозирует систему на исполняемые модули, контейнеры. Сюда попадают отдельные единицы развёртки, приложения, базы данных, брокеры сообщений и серверные API. Цель этого уровня: показать технологический стек, протоколы взаимодействия и схему размещения данных. Вопрос: из каких частей состоит система и как эти части общаются друг с другом?
Components
Уровень Components декомпозирует один конкретный контейнер, например бэкенд. На нём видны контроллеры, репозитории, сервисы и модули бизнес-логики. Цель: показать внутреннюю структуру исполняемого приложения и зоны его ответственности. Вопрос: как устроен конкретный сервис внутри?
Code
Уровень Code даёт максимальную техническую детализацию: схемы классов в нотации UML, интерфейсы, конкретные функции приложения. Цель: показать реализацию конкретного компонента в кодовой базе. На практике этот уровень обычно создаётся автоматически средствами IDE, а не рисуется вручную. Вопрос: как это реализовано в коде?
Чем рисовать
Инструментов для C4 хватает, но стоит выделить пять:
- Miro
- PlantUML
- Draw.io
- Mermaid
- Structurizr
Как нарисовать первую диаграмму
Дальше следует упражнение, которое лучше проходить не абстрактно, а на своём собственном проекте.
Шаг 0. Войдите в роль
Представьте, что вы Senior Solution Architect и вам нужно реализовать схему архитектуры, чтобы продемонстрировать её участникам своей команды. Дальше идут три версии одного и того же объяснения для трёх разных аудиторий.
Шаг 1. Объясните менеджеру
У менеджера бывает не хватает технической базы и понимания того, что происходит на вашем ноутбуке, поэтому здесь нужен самый высокий уровень абстракции: уровень Context.
Есть пользователь, он открывает наше приложение и делает заказ. Приложение уходит во внешний сервис оплаты и возвращает результат.
Шаг 2. Объясните джуну
Джун уже понимает, что куда ходит, возможно, даже какие протоколы используются, но его знаний пока недостаточно, чтобы разбираться на уровне репозиториев и контроллеров. Это уровень Containers.
Фронтенд отправляет REST-запрос на бэкенд, бэкенд сохраняет заказ в PostgreSQL и отправляет событие в Kafka, которое забирает сервис нотификаций.
Шаг 3. Объясните тимлиду
Тимлид прекрасно понимает всю информационную систему, и объяснять ему верхнеуровневую абстракцию незачем: здесь нужен уровень Components.
В сервисе заказов есть OrderController, который вызывает OrderService, тот идёт в OrderRepository за данными и публикует доменное событие через EventPublisher.
Один и тот же процесс, оформление заказа, описан три раза, и каждый раз на нужной для собеседника глубине. Ни одно из трёх объяснений не врёт и не упрощает до неправды: у каждого просто свой уровень детализации.
Итог
C4 описывает архитектуру системы через четыре уровня абстракции, и каждый из них отвечает на свой вопрос.
- Context - Кто пользуется и с чем взаимодействует?
- Containers - Из чего состоит и как части общаются?
- Components - Как устроен сервис внутри?
- Code - Как реализовано в коде?
Главное правило простое: каждый следующий уровень — это декомпозиция предыдущего. Не нужно рисовать всё сразу, нужно приближать камеру.