Кладовочка

О разном, чтобы было под рукой онлайн

C4 Model: документируем архитектуру за 4 шага с примерами и Mermaid

Проблема архитектурной документации: UML — слишком сложный и формальный, «рисуночки на доске» — слишком неформальные и устаревают через неделю. Нужно что-то посередине: достаточно структурированное, чтобы быть полезным, и достаточно простое, чтобы его реально поддерживать.

Саймон Браун (Simon Brown) решил эту проблему в 2006 году, предложив C4 Model — подход к документированию архитектуры на четырёх уровнях детализации. Идея гениально проста: вы «зумируетесь» в систему — от общего контекста до конкретных классов. Каждый уровень отвечает на вопросы своей аудитории, и ни один не пытается показать всё сразу.

Что такое C4 Model

C4 расшифровывается как Context, Containers, Components, Code — четыре уровня, от общего к частному. Это не нотация и не tooling, а подход к мышлению. Вы можете рисовать C4-диаграммы хоть в Draw.io, хоть на салфетке — важна структура, а не инструмент.

Какую проблему решает C4:

Проблема Решение C4
UML-диаграммы слишком сложны для бизнес-заказчиков Уровень Context показывает систему «глазами пользователя»
Наброски на доске теряются и не обновляются C4 даёт чёткую структуру: 4 уровня, каждый с целевой аудиторией
Разные стейкхолдеры хотят разную детализацию Каждый уровень отвечает на вопросы своей аудитории
Диаграммы становятся «лапшой» из всего подряд Правило: одна диаграмма — один уровень абстракции

Ключевой принцип: каждая диаграмма показывает ровно один уровень C4. Нельзя смешивать на одной диаграмме контейнеры и компоненты — это запутывает всех.

mindmap root((C4 Model)) Level 1: Context Система и её окружение Для бизнеса и команды Level 2: Containers Деплоимые единицы Для техлида и DevOps Level 3: Components Логическая структура контейнера Для разработчиков Level 4: Code UML-диаграммы классов Автогенерация из кода

Четыре уровня C4

Level 1: System Context (Контекст системы)

Что показывает: Систему как «чёрный ящик» в окружении пользователей и внешних систем. Это самый верхний уровень — взгляд с высоты 10 000 метров.

Аудитория: Бизнес-заказчики, product owners, новые члены команды, архитекторы смежных систем.

Ключевой вопрос: «Какую проблему решает наша система и с кем она взаимодействует?»

Правила:

  • Система — один прямоугольник в центре
  • Люди — синие фигурки
  • Внешние системы — серые прямоугольники
  • Стрелки показывают направление взаимодействия, подписаны намерением (не протоколом!)

Диаграмма контекста: Интернет-банк

Как читать диаграмму Context: У нас есть интернет-банк. Клиенты и операторы поддержки с ним работают. Система общается с мейнфреймом (за счетами), почтовым сервисом (за уведомлениями) и бюро кредитных историй (за скорингом). Всё. Никакой внутренней кухни — только внешние связи.

Что НЕ нужно показывать на уровне Context:

  • Базы данных (это деталь реализации)
  • Очереди сообщений
  • Балансировщики нагрузки
  • Микросервисы внутри системы

Level 2: Container (Контейнеры)

Что показывает: Деплоимые единицы внутри системы. Контейнер здесь — не Docker-контейнер! Это единица выполнения: веб-приложение, мобильное приложение, база данных, файловая система, serverless-функция.

Аудитория: Технический лид, DevOps-инженеры, разработчики.

Ключевой вопрос: «Из каких deployable-юнитов состоит система и как они общаются?»

Правила:

  • Система — граница (boundary), внутри — контейнеры
  • Каждый контейнер — отдельно развёртываемая единица
  • Стрелки подписываются протоколом/технологией взаимодействия

Диаграмма контейнеров: Интернет-банк

Как читать: Система состоит из девяти контейнеров. SPA и мобильное приложение — клиентские приложения. API Gateway принимает запросы, проксирует к сервисам (аутентификация, платежи). Данные хранятся в PostgreSQL, горячий кэш — в Redis, асинхронная связь — через RabbitMQ. Каждый контейнер можно развернуть, масштабировать и обновить независимо.

Level 3: Component (Компоненты)

Что показывает: Логическую структуру внутри одного контейнера. Компонент — это группа связанной функциональности за интерфейсом: контроллер, сервис, репозиторий, facade.

Аудитория: Разработчики конкретного сервиса, code review.

Ключевой вопрос: «Как организован код внутри этого контейнера?»

Диаграмма компонентов: API Gateway

Как читать: Router принимает HTTP-запросы, Auth Middleware проверяет JWT и rate limits. Затем запрос попадает в нужный контроллер (платежи, счета, переводы). Mainframe Facade инкапсулирует всю грязь общения с legacy-мейнфреймом по бинарному протоколу. Важно: мы не показываем здесь структуры данных, алгоритмы или конкретные функции — только архитектурно значимые компоненты.

Level 4: Code (Код)

Что показывает: UML-диаграммы классов, ER-диаграммы, диаграммы последовательностей — классические детальные диаграммы.

Аудитория: Разработчики, погружающиеся в конкретный модуль.

Ключевой вопрос: «Как реализован этот компонент на уровне классов?»

Рекомендация Саймона Брауна: Не рисуйте Code-диаграммы вручную. Они неизбежно устаревают. Вместо этого:

  • Генерируйте их автоматически из кода (IDE, инструменты вроде Structurizr DSL с автогенерацией)
  • Документируйте код через осмысленные имена классов/методов и javadoc/JSDoc/Python docstrings
  • Уровень Code нужен только для самых сложных и критичных компонентов — не для каждого класса в проекте

Дополнительные диаграммы C4

Помимо четырёх основных, C4 Model включает ещё три типа диаграмм:

Dynamic Diagram (Динамическая диаграмма)

Показывает временной порядок взаимодействия между элементами. Если статическая C4-диаграмма говорит «сервис A общается с сервисом B», то динамическая — «при логине пользователя сервис A сначала вызывает B, затем C, затем обновляет D».

Когда нужна: Для описания сложных сценариев, которые не очевидны из статической диаграммы: аутентификация с 2FA, распределённые транзакции, process manager в saga.

Deployment Diagram (Диаграмма развёртывания)

Показывает физическое размещение контейнеров на инфраструктуре: серверы, облачные регионы, Kubernetes-кластеры, сетевые зоны.

Когда нужна: Для DevOps, SRE, аудита безопасности. Отвечает на вопросы: «Где физически находятся данные?», «Какой контейнер в каком дата-центре?», «Что будет при падении зоны доступности?»

System Landscape Diagram (Ландшафт систем)

Показывает все системы организации на одном листе — enterprise-wide view. По сути, это System Context, но не для одной системы, а для всего ландшафта.

Когда нужна: Для CTO, enterprise-архитекторов, стратегического планирования. Помогает увидеть дублирование систем, интеграционные зоопарки и «бутылочные горлышки».

C4 vs UML: когда что использовать

Частый вопрос: «У нас уже есть UML, зачем C4?» Ответ: это не «или/или», это разные инструменты для разных задач.

Критерий C4 Model UML
Цель Коммуникация и понимание Детальное проектирование
Аудитория От бизнеса до разработчиков Разработчики и архитекторы
Порог входа Низкий: 4 уровня, простые фигуры Высокий: 14 типов диаграмм, сложная нотация
Поддержка в актуальном состоянии Легко: мало деталей, правила простые Тяжело: много деталей, быстро устаревают
Инструменты Structurizr, Mermaid, PlantUML, draw.io Enterprise Architect, Visual Paradigm, PlantUML
Когда использовать Онбординг, архитектурные ревью, стратегические решения Детальный дизайн модуля, генерация кода, формальные спецификации

Правило большого пальца:

  • Начинаете проект, обсуждаете архитектуру с командой, онбордите новичков → C4
  • Проектируете сложный алгоритм, генерируете код из модели, делаете reverse engineering → UML

Можно и нужно комбинировать: Level 1–3 в C4, а внутри Level 4 — UML-диаграммы классов, сгенерированные автоматически.

Когда C4 НЕ нужен

C4 Model решает конкретную проблему — документирование архитектуры для команды от 5 человек и системы с 3+ сервисами. Есть ситуации, где C4 — оверкилл:

Не нужен C4, если:

  • Вас двое и один сервис. Монолит на 5000 строк кода не нуждается в четырёх уровнях диаграмм. Одной архитектурной заметки в README достаточно.
  • Прототип на выброс. Если код живёт две недели и будет переписан — не тратьте время на документацию.
  • Команда не готова поддерживать. Лучше честно признать «мы не документируем архитектуру», чем создать кладбище устаревших диаграмм в Confluence.
  • Архитектура тривиальна. Статический сайт на Netlify без бэкенда. Context-диаграмма: один пользователь и один хостинг. Дальше можно не копать.

Хороший тест: покажите Context-диаграмму новому члену команды. Если он за 60 секунд понял, с чем работает система — уровень 1 уже оправдан. Если диаграмма тривиальна — достаточно текстового описания.

C4 + ADR = живая документация

C4-диаграммы отвечают на вопрос «как устроена система», но не отвечают на вопрос «почему именно так». Для «почему» существуют ADR — Architecture Decision Records.

Как они работают вместе:

flowchart LR A[Архитектурное решение] --> B[Создаём ADR: почему выбрали Kafka, а не RabbitMQ] B --> C[Обновляем C4-диаграммы: новый контейнер Kafka] C --> D[Оба файла в одном PR] D --> E[Будущий разработчик видит и ЧТО, и ПОЧЕМУ]

Практика: храните C4-диаграммы (Mermaid/Structurizr DSL) и ADR (Markdown) в одном репозитории, в папке docs/architecture/. Связывайте перекрёстными ссылками:

## Решение: используем Kafka для событий между сервисами

**Контекст:** см. C4 Container-диаграмму (`docs/architecture/containers.md`)
**Статус:** принято (2026-06-15)
...

Это создаёт единый источник правды: диаграммы показывают текущее состояние, ADR — историю и обоснование решений.

Типичные ошибки при использовании C4

1. Смешивание уровней на одной диаграмме

Самая частая ошибка: на диаграмме контейнеров вдруг появляются компоненты, а между контейнерами — детали БД. Результат: никто не понимает, на что смотреть.

Правило: Одна диаграмма — один C4-уровень. Если хочется показать детали контейнера — нарисуйте отдельную Component-диаграмму.

2. Непоследовательные названия

На Context-уровне система названа «Интернет-банк», на Container — «Banking Web App», на Component — «ibank-api». Три названия одного и того же запутывают всех.

Правило: Заведите глоссарий терминов на первом же уровне Context и используйте одинаковые названия на всех диаграммах.

3. Перегруженные диаграммы

«А давайте на Context-диаграмму добавим ещё 15 внешних систем, 8 типов пользователей и стрелки с протоколами». Нет. Context-диаграмма должна помещаться на одном экране и читаться за 30 секунд.

Правило: Если диаграмма не читается без зума — дробите на несколько. Ландшафт из 20 внешних систем → System Landscape Diagram. Разные сценарии для разных пользователей → несколько Context-диаграмм.

4. Устаревшая документация

Нарисовали, положили в Confluence, забыли. Через полгода появился новый сервис, старый переписали, а диаграммы остались прежними. Хуже отсутствия документации — только вводящая в заблуждение документация.

Правило: Встройте обновление C4-диаграмм в Definition of Done. Изменили архитектуру → обновили диаграммы в том же PR. Инструменты вроде Structurizr DSL позволяют хранить диаграммы как код в репозитории и обновлять вместе с кодом.

5. Перфекционизм в выборе инструмента

«Мы не можем начать документирование, потому что ещё не выбрали между Structurizr, IcePanel и LikeC4». C4 — это подход к мышлению, а не формат файла.

Правило: Начните с Mermaid в Markdown. Этого достаточно для 80% команд. Если перерастёте — мигрируете на Structurizr DSL, когда появится реальная потребность в продвинутых фичах.

Инструменты для C4-диаграмм

Инструмент Подход Плюсы Минусы
Structurizr DSL Диаграммы как код Единая модель, автогенерация, C4-нативный Нужно писать DSL, кривая обучения
Mermaid Текст → диаграмма Просто, встраивается в Markdown, GitHub/GitLab native Ограниченный layout, не хранит модель
PlantUML + C4 Текст → диаграмма Гибче Mermaid, больше стилей Синтаксис сложнее Mermaid
IcePanel Визуальный редактор Красиво, коллаборация в реальном времени Платный, vendor lock-in
LikeC4 Диаграммы как код C4-нативный, relation-based, интерактивные диаграммы, автолейаут (Graphviz) Молодой проект, нужен отдельный билд
Draw.io / diagrams.net Визуальный редактор Бесплатно, просто, все знают Ручное обновление, нет модели
LucidChart Визуальный редактор Коллаборация, шаблоны C4 Платный

Способы создания C4-диаграмм

Выбор инструмента зависит от того, где и для кого диаграмма. Три основных сценария:

1. В Markdown-документации (Mermaid)

То, что вы видели выше. Плюсы: живёт в том же репозитории, что и код, рендерится на GitHub/GitLab «из коробки», не требует установки. Минусы: статичный SVG, ручное позиционирование элементов (порядком объявления), нет интерактивности.

Когда: документация рядом с кодом, README, внутренние Confluence-страницы.

2. Интерактивная документация (LikeC4)

LikeC4 — DSL, где вы описываете не позиции элементов, а отношения между ними. Layout строит Graphviz автоматически. Результат — интерактивный SPA с зумом, навигацией и поиском, который можно задеплоить на GitHub Pages или Vercel.

Пример той же системы на LikeC4 DSL:

specification {
  element actor
  element system
  element container
  element component
}

model {
  customer = actor 'Клиент' { description 'Физлицо, пользователь интернет-банка' }
  operator = actor 'Оператор' { description 'Сотрудник колл-центра' }

  bankingSystem = system 'Интернет-банк' {
    spa = container 'SPA' { description 'Vue.js, Nginx' }
    mobile = container 'Mobile App' { description 'Flutter, iOS/Android' }
    admin = container 'Admin Panel' { description 'React, Nginx' }
    api = container 'API Gateway' { description 'Go, REST/GraphQL' }
    auth = container 'Auth Service' { description 'Go, OAuth 2.0' }
    payment = container 'Payment Service' { description 'Java, Spring Boot' }
    db = container 'PostgreSQL' { description 'Основная БД' }
    cache = container 'Redis' { description 'Кэш' }
    broker = container 'RabbitMQ' { description 'Брокер сообщений' }

    spa -> api 'REST/GraphQL'
    mobile -> api 'REST/GraphQL'
    admin -> api 'REST/GraphQL'
    api -> auth 'gRPC'
    api -> payment 'gRPC'
    api -> cache 'RESP'
    auth -> db 'SQL'
    payment -> db 'SQL'
    payment -> broker 'AMQP'
  }

  mainframe = system 'Мейнфрейм' { description 'Банковский бэкенд' }
  mailSystem = system 'Почтовый сервис' { description 'Email и SMS' }
  creditBureau = system 'Бюро кредитных историй'

  customer -> spa
  customer -> mobile
  operator -> admin
  payment -> mainframe 'ISO 8583'
  auth -> mailSystem 'SMTP'
  bankingSystem -> creditBureau 'REST/HTTPS'
}

views {
  view index {
    title 'Интернет-банк — System Context'
    include *
    exclude spa, mobile, admin, api, auth, payment, db, cache, broker
  }
  view of bankingSystem {
    title 'Интернет-банк — Containers'
    include *
  }
}

Запуск: npx likec4 start — поднимает dev-сервер с hot-reload. npx likec4 build -o dist — собирает статический сайт. npx likec4 export png — рендерит PNG для вставки в презентацию.

Когда: команда 5+, нужна «живая» документация, которую реально будут поддерживать. Порог входа выше Mermaid, но результат оправдывает усилия для долгоживущих проектов.

2.1. Для сравнения: та же диаграмма на Mermaid

Mermaid-версия той же Container-диаграммы — видно, что в Mermaid приходится вручную задавать взаимное расположение элементов (порядком объявления), а не описывать связи:

C4Container title Интернет-банк — Containers Person(customer, "Клиент") Person(operator, "Оператор") System_Ext(mainframe, "Мейнфрейм") System_Ext(mailSystem, "Почтовый сервис") System_Boundary(bankingSystem, "Интернет-банк") { Container(spa, "SPA", "Vue.js, Nginx") Container(mobile, "Mobile App", "Flutter") Container(admin, "Admin Panel", "React, Nginx") Container(api, "API Gateway", "Go, REST/GraphQL") Container(auth, "Auth Service", "Go, OAuth 2.0") Container(payment, "Payment Service", "Java, Spring Boot") ContainerDb(db, "PostgreSQL", "Основная БД") ContainerDb(cache, "Redis", "Кэш") Container(broker, "RabbitMQ", "Брокер сообщений") } Rel(customer, spa, "Использует", "HTTPS") Rel(customer, mobile, "Использует", "HTTPS") Rel(operator, admin, "Консультирует", "HTTPS") Rel(spa, api, "REST/GraphQL") Rel(mobile, api, "REST/GraphQL") Rel(admin, api, "REST/GraphQL") Rel(api, auth, "gRPC") Rel(api, payment, "gRPC") Rel(api, cache, "RESP") Rel(auth, db, "SQL/TCP") Rel(payment, db, "SQL/TCP") Rel(payment, broker, "AMQP") Rel(payment, mainframe, "ISO 8583") Rel(auth, mailSystem, "SMTP")

Основное отличие: в LikeC4 вы описываете отношения (customer -> spa), и Graphviz сам строит layout. В Mermaid вы управляете порядком объявления элементов — первые 4 идут в первый ряд, следующие 4 — во второй, и так далее. Это даёт контроль, но требует ручной подгонки при каждом изменении модели.

3. Презентации и статьи (Recraft / AI-генерация)

Для внешних материалов — блог-постов, презентаций, страниц «О продукте» — где нужен визуально привлекательный результат, а не структурная точность. Нейросети (Recraft, DALL-E, Midjourney) генерируют стилизованные диаграммы по текстовому описанию:

Промпт для Recraft (генерирует SVG): «C4 architecture diagram showing Internet Banking System with customer and operator on left, banking system box in center, mainframe, mail system and credit bureau systems on right. Clean structured layout, blue person icons, green system boxes, grey external systems. White background, readable text labels, arrows with descriptions.»

Результат — художественный вектор, который можно вставить в статью как иллюстрацию. Не подходит для документации (нельзя обновить модель), но отлично смотрится в маркетинговых материалах.

Пример сгенерированного SVG (Recraft):

C4 Context диаграмма, сгенерированная нейросетью Recraft

Когда: публичная статья, лендинг, слайды для конференции — где важнее «красиво», чем «актуально».

4. Быстрый старт (Draw.io)

Если нужно набросать диаграмму за 15 минут и показать на встрече — Draw.io с C4-шаблонами. Минус: ручное обновление, диаграмма живёт отдельно от кода.

Что выбрать: дерево решений

flowchart TD A[Нужна C4-диаграмма] --> B{Где будет жить?} B -->|В репозитории, рядом с кодом| C{Нужна интерактивность?} B -->|Презентация, статья, лендинг| D[Recraft / AI-генерация] C -->|Да, команда 5+| E[LikeC4 DSL] C -->|Нет, хватит статики| F[Mermaid в Markdown] B -->|Набросать на встречу| G[Draw.io]

Практический пример: с нуля до документации

Представьте: вы пришли в компанию, где есть продукт «Платформа управления доставкой». Документации нет, архитектура — в головах двух разработчиков (один из которых уволился). Строим C4 с нуля.

Шаг 1: System Context

Собираете встречу с product owner и техлидом. Задаёте три вопроса:

  1. Кто пользуется системой? (курьеры, диспетчеры, клиенты-отправители)
  2. Какие внешние системы задействованы? (GPS-трекинг, SMS-шлюз, платёжный шлюз, CRM)
  3. Какая главная ценность системы? (назначение заказов курьерам в реальном времени)

За 30 минут рисуете Context-диаграмму. Все кивают — да, это наша система.

Шаг 2: Containers

Спрашиваете у разработчиков: «Как это всё развёрнуто?» Выясняется:

  • Мобильное приложение курьера (React Native)
  • Веб-панель диспетчера (React)
  • Три бэкенд-сервиса в Kubernetes (orders, tracking, billing) + Kafka + PostgreSQL + Redis + S3
  • Два legacy-сервиса на Tomcat (клиентский портал, интеграция с CRM)

Рисуете Container-диаграмму. Техлид замечает: «Ого, а почему billing синхронно дёргает tracking? Надо поменять на события через Kafka». Уже окупилось.

Шаг 3: Components

Берёте самый сложный сервис — orders. Спрашиваете конкретного разработчика: «Как внутри устроен orders?» Он рисует на доске, вы переносите в Component-диаграмму. Выясняется:

  • OrderOrchestrator (ядро бизнес-логики) зависит напрямую от трёх репозиториев — кандидат на рефакторинг
  • Нет чёткой границы между API-слоем и доменной логикой
  • Интеграция с legacy-CRM сделана напрямую в контроллере (TODO на facade)

Уже три actionable инсайта — от диаграмм, нарисованных за пару часов.

Шаг 4: Code

Для orders-сервиса настраиваете автоэкспорт UML-диаграмм классов через IDE-плагин. Добавляете в README ссылку: «Диаграмму классов генерировать командой make uml». Ручных диаграмм Code-уровня — ноль.

Шаг 5: Интеграция в рабочий процесс

Кладёте диаграммы в docs/architecture/c4/ репозитория:

docs/architecture/c4/
├── context.md        # Level 1 — System Context
├── containers.md     # Level 2 — Container diagram
├── orders-component.md   # Level 3 — Orders service
├── tracking-component.md # Level 3 — Tracking service
└── README.md         # Как обновлять, соглашения об именах

Добавляете в Definition of Done команды: «Архитектурные изменения задокументированы в C4-диаграммах». Теперь каждый PR, меняющий архитектуру, должен обновить соответствующий .md-файл.

Результат

За один день вы получили:

  • 4 диаграммы (Context, Container, 2×Component) в репозитории
  • 3 архитектурных проблемы, о которых команда знала, но не фиксировала
  • Onboarding-материал для будущих разработчиков
  • Основу для Architecture Decision Records (ADR) по выявленным проблемам
  • Процесс поддержки документации, встроенный в Definition of Done

Самое ценное: через три месяца, когда команда вырастет вдвое, новичок открывает docs/architecture/c4/context.md — и за 10 минут понимает, с чем работает система, кто пользователи, какие внешние зависимости. Вместо двух недель «архитектурного онбординга через кофе-машину».

Заключение

C4 Model — не серебряная пуля, но лучший компромисс между «нет документации» и «300 страниц UML, которые никто не читает». Её сила — в простоте: четыре уровня, каждый для своей аудитории, без лишней церемонии.

Главные правила, которые стоит запомнить:

  1. Четыре уровня, не смешивать. Ровно как зум в Google Maps: страна → город → улица → дом. Не пытайтесь показать всё сразу.
  2. Начинайте с контекста. Если бизнес не понимает диаграмму — она бесполезна. Context-диаграмма должна быть понятна за 30 секунд.
  3. Диаграммы как код. Mermaid или Structurizr DSL в репозитории — обновляются вместе с кодом, ревьюятся в PR, живут рядом с тем, что документируют.
  4. Каждая диаграмма для своей аудитории. Не показывайте бизнесу компоненты, не показывайте разработчикам только контекст.
  5. Лучше простая диаграмма сегодня, чем идеальная — никогда. Начните с Mermaid в Markdown-файле. Если перерастёте — мигрируете на LikeC4 или Structurizr.
  6. C4 + ADR = полная картина. Диаграммы отвечают «что», ADR — «почему». Вместе — неубиваемая архитектурная документация.

С чего начать прямо сейчас:

  • Возьмите вашу текущую систему
  • Нарисуйте Context-диаграмму в Mermaid за 15 минут
  • Покажите коллеге — если понял с первого взгляда, вы на правильном пути
  • Положите в docs/architecture/c4/ и добавьте в Definition of Done

Связанные статьи на сайте