На архитектурной диаграмме нарисованы прямоугольники API, Backend, Kafka, Redis и несколько стрелок. Но где заканчивается система? Backend - это один процесс, десяток сервисов или слой? Стрелка означает HTTP-запрос, поток данных или просто зависимость? Автор всё это помнит. Остальные участники встречи угадывают.
Проблема не в прямоугольниках и стрелках. Проблема в том, что на одной картинке смешали разные масштабы и не объяснили обозначения.
C4 model задаёт общий набор уровней детализации: контекст, контейнеры, компоненты и код. Её главная польза не в четырёх обязательных диаграммах, а в дисциплине: одна схема отвечает на один вопрос, элементы имеют понятный тип, а переход к деталям происходит явно. На практике большинству команд достаточно контекстной диаграммы и диаграммы контейнеров. Остальные стоит создавать под конкретную задачу, а не для комплекта.
Что такое C4 model
Саймон Браун создал C4 model как способ делать «карты кода». Подобно карте города, описание системы можно рассматривать в нескольких масштабах: сначала увидеть окружение, затем приблизить саму систему, отдельное приложение и, наконец, реализацию. Модель возникла как более упорядоченная альтернатива произвольным схемам, а не как попытка заменить все виды технической документации.
Название C4 составлено из четырёх уровней:
| Уровень | Главный вопрос | Что показываем | Основная аудитория |
|---|---|---|---|
| 1. System Context | Для кого существует система и с чем она взаимодействует? | Людей, систему в фокусе и внешние системы | Разработчики, продукт, эксплуатация, бизнес |
| 2. Container | Из каких исполняемых приложений и хранилищ состоит система? | Web-приложения, API, фоновые процессы, базы данных, очереди | Техническая команда |
| 3. Component | Как устроен конкретный контейнер? | Крупные части кода с чёткими обязанностями и интерфейсами | Разработчики этой части системы |
| 4. Code | Как реализован отдельный компонент? | Классы, интерфейсы, функции и другие элементы кода | Разработчики, которые меняют реализацию |
В этой иерархии есть ещё один участник - человек. Это может быть пользователь, оператор, администратор или роль из соседней команды. Важно показать не должность в штатном расписании, а способ взаимодействия с системой.
C4 - это подход abstraction-first: сначала команда договаривается, какие сущности считает системой, контейнером и компонентом, а уже затем выбирает фигуры, цвета и инструмент. Официальное описание абстракций определяет простую вложенность: система состоит из контейнеров, контейнеры - из компонентов, а компоненты реализованы элементами кода.
Что C4 не описывает? Это не метод проектирования, не организационная структура и не полный шаблон архитектурной документации. Основные диаграммы показывают статическое устройство. Для бизнес-процессов, состояний, последовательностей, модели данных и эксплуатационных сценариев нужны дополнительные представления.
Сквозной пример: система оформления заказов
Разберём небольшой пример. Покупатель оформляет заказ в интернет-магазине. Наша система сохраняет заказ, запрашивает оплату и передаёт результат в службу доставки.
Пример намеренно простой. Его задача - показать, как меняется вопрос при переходе между уровнями. В реальной системе на диаграмме почти всегда окажется больше зависимостей. Это не повод уменьшать шрифт до состояния проверки зрения.
Уровень 1. System Context
Контекстная диаграмма проводит границу ответственности. Она показывает систему как один прямоугольник, людей вокруг неё и внешние системы. Внутреннее устройство пока неважно.
На этой схеме можно обсудить вопросы, которые часто теряются при преждевременном погружении в технологии:
- кто пользуется системой;
- где проходит её граница;
- какие внешние зависимости критичны;
- какие данные и действия пересекают границу;
- кто отвечает за соседние системы.
Контекстная диаграмма не должна показывать базу данных, внутреннюю очередь или отдельные микросервисы. Иначе мы одновременно говорим об окружении и внутреннем устройстве. Масштабы смешиваются, а следующий уровень теряет смысл.
Стрелки здесь обозначают направленное взаимодействие. Подпись отвечает на вопрос, что именно происходит: «запрашивает оплату» полезнее, чем «использует». Если важен протокол, его тоже стоит указать.
Уровень 2. Container
Теперь приблизим систему заказов. В терминологии C4 container - это исполняемое приложение или хранилище данных, а не обязательно Docker-контейнер. Клиентское Web-приложение, API, фоновый процесс, схема PostgreSQL и очередь сообщений могут быть контейнерами. Каждый из них образует отдельную границу выполнения или хранения данных. Автор C4 отдельно предупреждает о путанице с Docker.
На этом уровне становятся видны архитектурно значимые решения:
- интерфейс работает в браузере и обращается к API по HTTPS;
Order APIхранит заказы в отдельной схеме PostgreSQL;- длительная обработка отделена от синхронного запроса;
- worker получает сообщения через AMQP и обращается к внешним системам;
- у контейнеров указаны основная технология и обязанность.
Диаграмма контейнеров обычно приносит команде больше всего пользы. По ней можно провести обзор архитектуры, начать threat modeling, обсудить границы владения данными, развертывание и последствия отказа внешней зависимости.
Но C4-контейнер не равен Kubernetes Pod, виртуальной машине или серверу. Это логическая граница приложения или данных. На каких узлах и в скольких экземплярах всё работает, показывает отдельная deployment diagram.
С очередями есть тонкость. Лучше показывать конкретную очередь или topic как контейнер либо указывать их в подписи взаимодействия. Если нарисовать только общий message broker, схема скроет связь между производителем и потребителем. Официальная рекомендация C4 предлагает моделировать очередь или topic, а не весь брокер как один контейнер.
Уровень 3. Component
Компонентная диаграмма приближает один контейнер. Компонент в C4 - это группа связанной функциональности за понятным интерфейсом, а не любой пакет или каталог. Один компонент может занимать несколько пакетов, а один пакет иногда содержит детали нескольких компонентов. Важно архитектурное назначение, а не дерево файлов.
В примере HTTP Handler отвечает за транспортный контракт, Order Service - за правила оформления заказа, Order Repository - за сохранение данных, а Event Publisher - за публикацию события. Диаграмма показывает зависимости между ними и связь с контейнерами за пределами Order API.
Такая схема полезна, если внутри контейнера есть устойчивые архитектурные границы. Например, команда обсуждает разделение доменной логики и инфраструктуры, проверяет направление зависимостей или планирует изменение большого модуля.
Когда контейнер невелик и его устройство очевидно из кода, компонентная диаграмма создаёт больше работы, чем пользы. Она меняется чаще контекста и контейнеров. FAQ C4 прямо отмечает эту разницу: активная разработка быстро меняет компоненты, а контекст системы обычно остаётся стабильным.
Уровень 4. Code
Уровень кода показывает реализацию компонента: классы, интерфейсы, функции, таблицы методов или другие конструкции языка. Здесь можно использовать UML class diagram, схему зависимостей пакетов или представление из IDE.
Правило простое: чем ближе диаграмма к исходному коду, тем дороже поддерживать её вручную.
Дополнительные диаграммы
Четыре основных уровня отвечают на вопрос «из чего состоит система». Иногда этого недостаточно. C4 также определяет три дополнительных представления: system landscape, dynamic и deployment diagram.
System landscape показывает несколько систем организации и связи между ними. Он полезен для общей карты ландшафта, но легко превращается в нечитаемый каталог. Для большой организации лучше хранить модель и строить из неё несколько представлений по областям ответственности.
Dynamic diagram показывает один сценарий как упорядоченную последовательность взаимодействий. Она не заменяет полноценную UML sequence diagram, но помогает объяснить, как уже знакомые элементы участвуют в конкретном запросе.
Статическая диаграмма контейнеров сообщает, что Order API связан с базой и очередью. Динамическая добавляет порядок: API сначала сохраняет заказ, затем публикует событие и возвращает ответ. Если нужно показать ветвления, циклы, тайм-ауты и параллельную работу, удобнее перейти к UML sequence diagram.
Deployment diagram связывает экземпляры контейнеров с узлами развёртывания: устройствами, виртуальными машинами, Kubernetes-кластерами, регионами и сетевыми зонами. Она отвечает на вопросы доступности, изоляции и топологии, которые намеренно отсутствуют на обычной container diagram.
Как сделать диаграмму понятной без рассказчика
C4 не требует определённого визуального языка. Можно использовать прямоугольники Excalidraw, UML-нотацию, PlantUML или собственный стиль. Такая свобода не отменяет правил. Рекомендации по нотации предлагают проверять, может ли диаграмма в основном объяснить себя сама.
Укажите тип, название и обязанность элемента
Подпись Payment Service сообщает только имя. Полезный элемент выглядит так:
Payment Service
[Container: Go]
Авторизует и возвращает платежи
Тип не позволяет случайно принять внешний software system за внутренний контейнер. Короткое описание объясняет обязанность. Технология помогает оценить ограничения, но не должна заменять назначение.
Подписывайте отношения глаголом
Стрелка A -> B без подписи заставляет читателя угадывать. Использует немногим лучше. Напишите наблюдаемое действие:
- «запрашивает статус платежа по HTTPS/JSON»;
- «публикует
OrderCreatedв topicordersчерез AMQP»; - «читает историю заказов по SQL/TCP».
Направление стрелки должно совпадать с текстом. Если линия показывает поток данных, не описывайте её как зависимость в обратную сторону.
Не смешивайте уровни
Самая частая ошибка - поместить рядом Покупателя, Order API, класс OrderRepository, таблицу orders и Kubernetes-кластер. Каждый элемент может быть важен, но вместе они не отвечают ни на один вопрос.
Выберите масштаб. Детали следующего уровня покажите на отдельной диаграмме и сохраните те же названия. Переход от Системы заказов к Order API, а затем к Order Service должен быть похож на приближение карты, а не на знакомство с тремя разными системами.
Ограничьте историю одной диаграммы
Даже одинаковый уровень не требует показывать всё сразу. Для десятков микросервисов полезнее сделать обзорную схему и несколько focused views - представлений вокруг конкретного сервиса, бизнес-сценария или области. Официальный FAQ о масштабировании C4 рекомендует делить сложную картину на несколько простых диаграмм с определённым фокусом.
Название должно сообщать тип и границу: «Container diagram системы заказов» или «Component diagram Order API». Легенда нужна, если цвет, форма или стиль линии несут смысл.
Проверяйте диаграмму вопросами
Перед публикацией дайте схему человеку, который не участвовал в её создании. Попросите ответить:
- Какой это тип диаграммы и что входит в её границу?
- Что делает каждый элемент?
- Что означает каждая стрелка?
- Где наша ответственность, а где внешняя?
- Какие технологии и протоколы архитектурно значимы?
Это сокращённая версия официального checklist C4. Если ответы требуют пятиминутного вступления автора, диаграмма пока работает как фон для презентации, а не как документация.
Excalidraw или diagrams as code
Выбор инструмента зависит от стадии работы, а не от архитектурной зрелости команды.
| Подход | Когда удобен | Сильная сторона | Ограничение |
|---|---|---|---|
| Excalidraw, Miro, diagrams.net | Совместная сессия, ранний дизайн, редкая правка | Свободное ручное редактирование и низкий порог входа | Трудно поддерживать согласованность многих схем |
| Structurizr DSL | Несколько C4-представлений одной системы | Одна модель, фильтры, динамические и deployment views | Отдельный DSL и ограничения автоматической компоновки |
| C4-PlantUML | Команда уже использует PlantUML | Текстовые diff, знакомая экосистема | Макросы поверх PlantUML, компоновка требует настройки |
| Mermaid C4 | Markdown уже рендерит Mermaid | Схема находится рядом с текстом | C4-синтаксис пока экспериментальный |
| Генерация из кода и инфраструктуры | Детальные и часто меняющиеся представления | Меньше ручной синхронизации | Автоматически найденная связь ещё не объясняет архитектурное намерение |
C4-PlantUML предоставляет макросы для основных и дополнительных C4-диаграмм. Mermaid тоже поддерживает C4, но документация помечает этот тип диаграмм как экспериментальный: синтаксис и свойства могут измениться.
Сравнение с другими подходами
C4 часто сравнивают с UML, ArchiMate и обычными схемами. Они решают пересекающиеся, но не одинаковые задачи.
| Подход | Что стандартизирует | Где особенно полезен | Где C4 проще |
|---|---|---|---|
| Произвольные boxes and arrows | Ничего, правила задаёт автор | Быстрый разговор у доски | Общие уровни, типы элементов и переход к деталям |
| UML | Язык моделирования структуры и поведения | Классы, последовательности, состояния, активности, строгая нотация | Небольшой словарь для обзора архитектуры и более низкий порог входа |
| ArchiMate | Язык enterprise architecture | Связь бизнеса, приложений, данных, технологий и стратегии | Детали внутреннего устройства одной программной системы |
| arc42 | Структуру архитектурной документации | Полное описание контекста, решений, рисков, качества и эксплуатации | Только визуальная декомпозиция системы по масштабам |
| C4 | Уровни абстракции и типы архитектурных представлений | Коммуникация устройства программной системы | Не заменяет остальные подходы там, где нужны их специальные представления |
Если команда уверенно применяет UML или ArchiMate и читатели понимают схемы, переходить на C4 ради моды незачем. Сам автор C4 формулирует тот же практический совет: работающую нотацию стоит сохранить, а C4 можно использовать как упрощение или дополнение.
Плюсы C4 model
Низкий порог входа. Четыре типа сущностей проще освоить, чем полноценный язык моделирования. Участники быстрее переходят к обсуждению системы.
Явный масштаб. Контекст не спорит за место с классами и узлами Kubernetes. Читатель заранее понимает степень детализации.
Разные представления для разных аудиторий. Руководителю продукта может быть достаточно контекста. Разработчику API пригодятся контейнеры и компоненты. Эксплуатации - deployment diagram.
Нотация не привязана к инструменту. Схему можно начать на доске, перенести в Excalidraw, а затем описать в Structurizr DSL.
Подходит и для проектирования, и для исследования существующей системы. В greenfield диаграммы фиксируют намерение. В brownfield они помогают сформулировать фактические границы и обнаружить расхождения между документацией и кодом.
Ограничения и минусы
C4 описывает не всё. Модель данных, состояния, алгоритмы, бизнес-процессы, эксплуатационные процедуры и архитектурные решения останутся за её пределами. Их нужно документировать отдельно.
Границы не обнаруживаются автоматически. C4 даёт словарь, но не решает, считать ли микросервис отдельной системой, кому принадлежит очередь и где заканчивается контейнер. Эти решения требуют знания предметной области и ответственности команд.
Ручные диаграммы устаревают. Особенно быстро меняются компоненты и код. Чем детальнее схема, тем сильнее аргумент в пользу генерации или отказа от неё.
Свобода нотации может вернуть исходную проблему. Если каждая команда выбирает свои цвета, формы и смысл стрелок, формально это всё ещё C4, но читать набор диаграмм снова трудно. Нужны общие правила внутри организации.
Большие системы не помещаются на один лист. Модель масштабируется через несколько focused views, а не через бесконечное расширение холста. Для этого ручной инструмент со временем может стать неудобным.
Схема создаёт иллюзию точности. Прямоугольник с аккуратным названием не доказывает, что компонент действительно изолирован, а стрелка не гарантирует соблюдение контракта. Диаграмму нужно сверять с кодом, инфраструктурой и наблюдаемым поведением.
Итог
C4 model полезна не потому, что превращает архитектуру в четыре картинки. Она заставляет перед рисованием ответить: какой вопрос мы обсуждаем, где проходит граница и какой уровень деталей нужен читателю.
Контекст показывает место системы в мире. Контейнеры объясняют её крупные исполняемые части и хранилища. Компоненты приближают только сложные области. Код лучше показывать по запросу, если ручная схема не окупает поддержку. Dynamic и deployment diagrams добавляют сценарий и топологию, но не смешивают их со статической структурой.
Правило простое: рисуйте минимальный набор представлений, который помогает принять решение или понять систему. Всё остальное - обслуживание прямоугольников.
Дополнительные материалы
- C4 model: Introduction
- C4 model: Diagrams
- C4 model: Software architecture diagram review checklist
- Structurizr DSL
- Structurizr DSL: Dynamic view
- Structurizr DSL: Deployment view
- C4-PlantUML
- Mermaid C4 diagrams
Комментарии в Telegram-группе!