Архитектурные схемы часто начинают жить отдельной жизнью. Их рисуют для презентации, защиты решения, согласования или просто потому, что “без схемы обсуждать сложно”. Это правда. Но дальше появляются две крайности.
Первая: схема становится украшением. На ней много коробок и стрелок, она выглядит профессионально, но почти не помогает принимать решения.
Вторая: схема превращается в суррогат архитектуры. Команда считает, что если boxes and arrows уже есть, то архитектурная работа как будто сделана.
Поэтому C4-модель полезно воспринимать очень прагматично. Не как “ещё один стандарт диаграмм” и не как способ всё подписать правильными слоями, а как хороший формат разговора о системе на разных уровнях приближения.
Для аналитика это особенно полезно. C4 помогает:
- не смешивать контекст системы с её внутренним устройством;
- не пытаться на одной схеме показать вообще всё;
- объяснять архитектуру разным ролям на разном уровне детализации;
- и главное — удерживать связь между смыслом системы и тем, как она потом будет разложена на контуры, компоненты и взаимодействия.
В прошлой статье мы разбирали, как доменная модель задаёт границы. Теперь посмотрим, как эти границы показать на C4-схемах. Продолжим серию на примере лунной базы и разберём, как аналитик может использовать C4 не для “красивой картинки”, а для более точного архитектурного мышления.
В статье
- Почему одной схемы почти всегда недостаточно
- Что именно даёт C4-модель
- System Context: где границы системы
- Container: как появляется рабочая архитектурная форма
- Component: где начинается полезная детализация
- Лунная база: пример C4-мышления на одном кейсе
- C4 на сквозном сценарии
- Типичные ошибки при работе со схемами
- Короткий checklist перед публикацией схемы
- Что дальше
Почему одной схемы почти всегда недостаточно
Проблема многих архитектурных обсуждений в том, что команда пытается уместить на одной диаграмме сразу всё:
- бизнес-контекст;
- пользователей и внешние системы;
- внутренние сервисы;
- базы данных;
- очереди;
- компоненты;
- deployment (как и где всё развёрнуто);
- потоки данных;
- иногда ещё и инфраструктуру.
В результате появляется схема, которая:
- выглядит содержательно;
- почти никому не врёт полностью;
- но и не помогает никому по-настоящему.
Для аналитика это особенно опасно, потому что такая схема создаёт ложное ощущение точности. Кажется, что всё уже разложено. На деле смешаны разные уровни разговора.
C4 полезен именно тем, что не даёт делать вид, будто один рисунок может заменить все остальные.
Что именно даёт C4-модель
Главная ценность C4 не в нотации, а в дисциплине масштаба.
Она помогает разделить:
- контекст системы — где вообще границы и с кем система взаимодействует;
- контейнерный уровень — из каких крупных частей система состоит;
- компонентный уровень — как устроены ключевые части внутри;
- при необходимости — уровень кода, если нужен совсем детальный разговор.
Для аналитика особенно важны первые три уровня.
Почему:
- на уровне context становится видно, где у системы настоящие внешние границы;
- на уровне containers становится видно, как архитектура отвечает на требования;
- на уровне components можно обсуждать важные части без сваливания в код.
То есть C4 позволяет переводить разговор:
- от требований и ролей;
- к архитектурной форме;
- и дальше к реализуемой детализации.
Коротко это удобно держать в виде таблицы:
| Уровень C4 | На какой вопрос отвечает | Кому особенно полезен | Что показываем на лунной базе |
|---|---|---|---|
| System Context | Где границы системы и кто с ней взаимодействует? | менеджеры, аналитики, заказчик | база, экипаж, Земля, логистика, внешние команды |
| Container | Из каких крупных частей состоит система? | аналитики, архитекторы, тимлиды | контуры жизнеобеспечения, энергетики, логистики, телеметрии |
| Component | Как устроена ключевая часть внутри? | архитекторы, разработчики | внутренности контура логистики или модуля локальных решений |
| Code | Как это реализовано в коде? | разработчики | обычно не рисуется вручную |
System Context: где границы системы
System Context отвечает на базовый вопрос:
Где заканчивается наша система и кто с ней взаимодействует?
Это очень простой уровень, но именно здесь часто закладывается половина будущих ошибок.
Если границы системы неясны, дальше почти неизбежно начинаются проблемы:
- внутреннюю систему рисуют как внешнюю;
- внешний процесс принимают за часть своей ответственности;
- интеграцию считают “просто ещё одним сервисом”;
- ownership (зона ответственности за часть системы) становится мутным;
- архитектура начинает компенсировать неясные границы техническими костылями.
В кейсе лунной базы system context должен как минимум различать:
- саму базу как локальный operational контур;
- наземный контур управления и анализа;
- внешний логистический контур поставок;
- экипаж;
- роботизированные платформы и системы автоматизации;
- внешние источники миссионных ограничений и команд.
Если всё это смешать на первой схеме, команда быстро перестанет понимать, что вообще находится “внутри системы”. Простейшая System Context-диаграмма для базы могла бы выглядеть так:
(пользователь)"] -->|команды, подтверждения| base["Система управления
лунной базой"] base -->|статус, телеметрия| ground["Наземный центр
(внешний)"] ground -->|планы, ограничения миссии| base base -->|заявки на пополнение| supply["Логистический
контур поставок (внешний)"] base -->|задания| robots["Роботизированные платформы
(внешние к контуру, но управляемые им)"]
flowchart TD
crew["Экипаж
(пользователь)"] -->|команды, подтверждения| base["Система управления
лунной базой"]
base -->|статус, телеметрия| ground["Наземный центр
(внешний)"]
ground -->|планы, ограничения миссии| base
base -->|заявки на пополнение| supply["Логистический
контур поставок (внешний)"]
base -->|задания| robots["Роботизированные платформы
(внешние к контуру, но управляемые им)"]
Здесь видно главное, ради чего нужен этот уровень: что внутри (система управления базой) и что снаружи (Земля, поставки, роботы, экипаж) — без единой детали о внутреннем устройстве.
Container: как появляется рабочая архитектурная форма
Container level отвечает уже на другой вопрос:
Какие крупные части внутри системы нужны, чтобы она выполняла свои задачи?
Это не обязательно контейнеры в Docker и не обязательно будущие микросервисы. Это крупные архитектурные блоки, у которых есть:
- своя роль;
- свой контур ответственности;
- свои взаимодействия;
- свой стиль хранения или обработки данных.
В кейсе лунной базы на этом уровне уже могут появиться, например:
- контур жизнеобеспечения;
- контур энергосистемы;
- контур логистики и запасов;
- контур роботизированных операций;
- контур телеметрии и инцидентов;
- контур синхронизации с наземным планированием.
Именно на этом уровне аналитика особенно полезна архитектуре. Потому что здесь уже видно:
- какие требования породили эти блоки;
- где проходят реальные границы смысла;
- какие взаимодействия должны быть синхронными;
- где необходима асинхронность и eventual consistency (согласованность «не сразу, но в итоге»);
- где автономность важнее централизованного контроля.
То есть container diagram — это уже не картинка “из чего система состоит”, а объяснение, как требования превратились в архитектурную форму.
Component: где начинается полезная детализация
Component level нужен тогда, когда о контейнере уже недостаточно говорить как об одной коробке.
На этом уровне полезно показывать:
- внутренние компоненты;
- ключевые зависимости;
- потоки решений;
- границы между domain logic (доменной логикой), integration logic (интеграциями), orchestration (оркестрацией) и storage access (доступом к данным).
Для аналитика этот уровень полезен не всегда. Но он особенно важен в двух случаях:
- когда нужно проверить, не размазан ли смысл внутри одной крупной части системы;
- когда команда пытается спрятать реальную сложность за словом “сервис”.
Например, “контур логистики” в лунной базе может казаться единым. Но на компонентном уровне быстро выясняется, что внутри него живут очень разные вещи:
- модель критичных резервов;
- планирование пополнения;
- подтверждение выдачи и использования;
- reconciliation с наземным контуром;
- инцидентные сценарии дефицита.
Если этого уровня никогда не показывать, команда может долго жить с ложным ощущением простоты.
Лунная база: пример C4-мышления на одном кейсе
Хороший способ использовать C4 — не рисовать все уровни сразу, а переходить между ними вопросами.
Вопрос 1. Где граница системы?
Здесь рождается System Context:
- база;
- экипаж;
- наземный центр;
- поставщики и логистический контур;
- внешние источники команд и ограничений.
Вопрос 2. Какие крупные части внутри системы действительно самостоятельны?
Здесь рождается Container level:
- жизнеобеспечение;
- энергосистема;
- логистика;
- робототехника;
- телеметрия и обработка инцидентов;
- контур синхронизации с наземным планированием.
Вопрос 3. Где один контейнер слишком абстрактен?
Здесь появляется Component level:
- внутри логистики;
- внутри контура телеметрии;
- внутри управления роботами;
- внутри модуля принятия локальных решений в деградационном режиме.
flowchart TD
A["Система лунной базы"] --> B["System Context"]
B --> C["Границы: база, Земля, экипаж, логистика"]
C --> D["Container level"]
D --> E["Жизнеобеспечение"]
D --> F["Энергетика"]
D --> G["Логистика"]
D --> H["Робототехника"]
D --> I["Телеметрия и инциденты"]
D --> J["Синхронизация с наземным планированием"]
G --> K["Component level"]
I --> K
H --> K
Главная мысль здесь простая: C4 полезен не тогда, когда все четыре уровня нарисованы, а тогда, когда команда понимает, какой вопрос сейчас обсуждает.
C4 на сквозном сценарии
Проверим C4 на сквозном сценарии серии: связь с Землёй пропала на 40 минут, а энергобюджет просел. Один и тот же кейс на трёх уровнях отвечает на разные вопросы:
- Context — кто вообще участвует в решении, когда Земли нет? На этом уровне видно, что наземный центр временно недоступен, и решение остаётся между экипажем и системой базы.
- Container — какие контуры нужны для автономной реакции? Контур принятия решений, жизнеобеспечение, энергетика и приоритизация нагрузок должны работать без внешнего канала.
- Component — что внутри контура локальных решений? Классификатор критичности операций, политика деградации, журнал аудита, модуль приоритизации потребителей энергии.
На container-уровне автономная реакция выглядит так:
решений"] dec -->|приоритеты нагрузок| energy["Энергетика"] dec -->|пороги и резервы| life["Жизнеобеспечение"] dec -->|что отложить| log["Логистика"] dec -.->|буферизуется до связи| ground["Наземный центр
(недоступен 40 мин)"]
flowchart TD
crew["Экипаж"] -->|решение| dec["Контур локальных
решений"]
dec -->|приоритеты нагрузок| energy["Энергетика"]
dec -->|пороги и резервы| life["Жизнеобеспечение"]
dec -->|что отложить| log["Логистика"]
dec -.->|буферизуется до связи| ground["Наземный центр
(недоступен 40 мин)"]
Обратите внимание: пунктирная связь с Землёй показывает ровно то, что задал доменный анализ из прошлых статей — критичное решение не должно ждать внешний контур. C4 здесь не придумывает архитектуру, а делает видимым уже принятый драйвер.
Типичные ошибки при работе со схемами
1. Рисовать всё сразу
Это самая частая ошибка. Одна перегруженная схема редко помогает лучше, чем три более точные.
2. Рисовать уровни как будто они одинаково полезны всегда
Иногда достаточно context и containers. Иногда нужен component level. Иногда code level вообще не нужен. Это не лестница обязательности, а набор инструментов.
3. Подменять смысл нотацией
Можно очень аккуратно подписать diagram как C4, но если на ней не видно:
- границ;
- контуров ответственности;
- архитектурных драйверов;
- важных взаимодействий;
то это просто аккуратная картинка, а не полезная модель.
4. Считать контейнеры уже будущими сервисами
Это особенно опасно. Container в C4 — это прежде всего крупная архитектурная часть системы, а не автоматически отдельная разворачиваемая единица (deployable unit).
5. Не показывать, зачем схема вообще существует
Каждая схема должна отвечать на вопрос. Если вопрос неясен, схема почти наверняка лишняя.
Короткий checklist перед публикацией схемы
Перед тем как показывать схему команде, полезно проверить:
- Какой именно уровень C4 здесь используется?
- На какой вопрос эта схема отвечает?
- Не смешаны ли на ней разные масштабы разговора?
- Видны ли реальные границы системы и ownership?
- Понимает ли читатель, почему система имеет именно такую форму?
- Не делает ли схема вид, что решение уже найдено, хотя вопрос ещё не прояснён?
- Помогает ли она следующему разговору, а не только текущей презентации?
Если ответов на эти вопросы нет, то схема, скорее всего, красивая, но не очень полезная.
Что дальше
На этом замыкается аналитическая арка серии: от рамки кейса и роли аналитика — через problem statement, требования-драйверы и доменную модель — к C4 как способу показать всё это на нужном уровне. Дальше начинается вторая арка — про реализацию и эксплуатацию. Следующая статья серии — взаимодействия и интеграции — про то, как аналитика и архитектура по-разному смотрят на REST, события, команды и очереди, и почему именно здесь часто ломается кажущаяся простота системы.
Комментарии