Режим чтения выключен

Взрывная C4 диаграмма

Дата
Категория
Architecture
Чтение
10 минут чтения
Теги
#C4#architecture#documentation#diagram

Взрывная C4-диаграмма

Материал этого поста вырос из лекции для участников Студенческой ИТ-Лаборатории.

Тема лекции звучала просто, но на практике оказывается неудобной: как объяснить архитектуру своего проекта так, чтобы её поняли и менеджер, и джун, и тимлид, причём не рисуя один и тот же чертёж для всех троих. Ответ на этот вопрос простой: C4-диаграмма. У неё четыре уровня абстракции, и дальше пойдёт речь о том, что это такое, зачем она нужна, какими инструментами её рисовать и как сделать свою первую диаграмму на практике.

Что такое C4 и зачем она нужна

C4-диаграмма: способ визуализации архитектуры программного обеспечения через четыре уровня абстракции: Context, Containers, Components и Code. Идея в том, чтобы не пытаться уместить всю систему в одну схему, а показывать её слоями, от общей картины до конкретных классов в коде.

Главная задача диаграммы в том, чтобы быстро и понятно объяснить архитектуру ПО всей команде и бизнесу. В рамках лаборатории она решает конкретную практическую задачу: помогает участнику лучше понять архитектурное решение собственного проекта, причём настолько, чтобы его понимали и руководитель отдела, и команда разработки.

Четыре уровня абстракции

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

Context

Уровень Context показывает верхнеуровневую схему системы целиком. На нём изображена сама система как единый объект, типы её пользователей и внешние интеграции, с которыми она взаимодействует. Цель уровня в том, чтобы показать границы системы и её окружение. Вопрос, на который он отвечает: кто пользуется системой и с чем она взаимодействует?

Containers

Уровень Containers декомпозирует систему на исполняемые модули, контейнеры. Сюда попадают отдельные единицы развёртки, приложения, базы данных, брокеры сообщений и серверные API. Цель этого уровня: показать технологический стек, протоколы взаимодействия и схему размещения данных. Вопрос: из каких частей состоит система и как эти части общаются друг с другом?

Components

Уровень Components декомпозирует один конкретный контейнер, например бэкенд. На нём видны контроллеры, репозитории, сервисы и модули бизнес-логики. Цель: показать внутреннюю структуру исполняемого приложения и зоны его ответственности. Вопрос: как устроен конкретный сервис внутри?

Code

Уровень Code даёт максимальную техническую детализацию: схемы классов в нотации UML, интерфейсы, конкретные функции приложения. Цель: показать реализацию конкретного компонента в кодовой базе. На практике этот уровень обычно создаётся автоматически средствами IDE, а не рисуется вручную. Вопрос: как это реализовано в коде?

Чем рисовать

Инструментов для C4 хватает, но стоит выделить пять:

  1. Miro
  2. PlantUML
  3. Draw.io
  4. Mermaid
  5. Structurizr

Как нарисовать первую диаграмму

Дальше следует упражнение, которое лучше проходить не абстрактно, а на своём собственном проекте.

Шаг 0. Войдите в роль

Представьте, что вы Senior Solution Architect и вам нужно реализовать схему архитектуры, чтобы продемонстрировать её участникам своей команды. Дальше идут три версии одного и того же объяснения для трёх разных аудиторий.

Шаг 1. Объясните менеджеру

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

Есть пользователь, он открывает наше приложение и делает заказ. Приложение уходит во внешний сервис оплаты и возвращает результат.

Шаг 2. Объясните джуну

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

Фронтенд отправляет REST-запрос на бэкенд, бэкенд сохраняет заказ в PostgreSQL и отправляет событие в Kafka, которое забирает сервис нотификаций.

Шаг 3. Объясните тимлиду

Тимлид прекрасно понимает всю информационную систему, и объяснять ему верхнеуровневую абстракцию незачем: здесь нужен уровень Components.

В сервисе заказов есть OrderController, который вызывает OrderService, тот идёт в OrderRepository за данными и публикует доменное событие через EventPublisher.

Один и тот же процесс, оформление заказа, описан три раза, и каждый раз на нужной для собеседника глубине. Ни одно из трёх объяснений не врёт и не упрощает до неправды: у каждого просто свой уровень детализации.

Итог

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

  • Context - Кто пользуется и с чем взаимодействует?
  • Containers - Из чего состоит и как части общаются?
  • Components - Как устроен сервис внутри?
  • Code - Как реализовано в коде?

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