Схемы в документах: когда рисовать и что именно
03:40, деградация оплаты. Дежурный открывает страницу вики «Архитектура биллинга»: двадцать
три прямоугольника, тридцать одна стрелка, нарисовано в draw.io полтора года назад. Он находит
стрелку payments-api → notifier и делает единственный вывод, который эта стрелка допускает:
notifier вызывается синхронно, значит его тормоза держат наш пул соединений. Двадцать пять
минут уходит на поиск таймаутов, которых нет.
На самом деле notifier читает из Kafka. Стрелка на схеме означала «данные в конечном счёте
попадают туда» — так её задумал автор, который рисовал контекст для презентации директору.
Схема не соврала буквально. Она просто не сказала, что означает стрелка, и дежурный достроил
самое естественное значение — вызов. В той же вики, тремя экранами ниже, лежала правильная
картинка, но она называлась «Взаимодействие сервисов v2 (актуально)», а первая —
«Архитектура биллинга», и поиск выдавал первую.
Схема — это утверждение, а не украшение. Она существует ради одного вопроса одного читателя и обязана быть однозначной ровно в том, что нужно для ответа. Картинка, которую нельзя пересказать одним предложением, ничего не сообщает — она занимает место и создаёт ощущение, что тема раскрыта.
Это та же рамка, что и во всём треке — читатель и решение, только применённая к невербальной части документа. Разница в том, что у прозы есть встроенные предохранители: неоднозначное предложение обычно звучит коряво, и автор это чувствует. У схемы предохранителей нет. Красивая, ровная, симметричная картинка выглядит убедительно независимо от того, верна она и понятна ли. Именно поэтому схемы врут чаще текста и обнаруживается это позже.
Схема отвечает на вопрос, а не «показывает систему»
Самая дешёвая проверка: попробуйте написать под картинкой подпись в форме утверждения. Не темы («Архитектура сервиса платежей»), а именно утверждения — то, что читатель должен унести. Если утверждение не формулируется, схема не нужна: вы нарисовали инвентаризацию, а не сообщение.
Три пары «плохо — переписано», на одном и том же рисунке:
| Плохо (тема) | Переписано (утверждение) |
|---|---|
| «Архитектура сервиса платежей» | «Все записи идут только через payments-api; отчётность читает реплику и отстаёт до 5 минут» |
| «Схема обработки заказа» | «Заказ становится оплаченным только после подтверждения от банка; всё, что до этого, можно отменить без денежных последствий» |
| «Взаимодействие компонентов» | «Единственная синхронная зависимость на пути пользователя — антифрод; остальные пять вызовов асинхронные и их падение не роняет оплату» |
Слева читатель не знает, зачем смотреть. Справа он уже знает вывод и смотрит на картинку, чтобы его проверить, — это принципиально другое чтение, быстрое и внимательное. Приём тот же, что в структуре: вывод впереди, обоснование следом.
Второй эффект подписи-утверждения: она отсекает лишнее. Как только вы написали «все записи
идут через payments-api», становится видно, что кэш, три вспомогательных крона и связь
с системой рассылок к этому утверждению отношения не имеют — и их можно убрать. Схема
худеет с двадцати трёх коробок до пяти, и её начинают читать.
Что глаз делает лучше текста, а что заметно хуже
Картинка не «понятнее» текста. Она сильна в другом: зрение обрабатывает положение, форму, размер и группировку параллельно, а текст читается последовательно. Отсюда прямое следствие: диаграмма выигрывает там, где важны отношения между многими объектами сразу, и проигрывает там, где важна логика — условие, причина, отрицание, количество.
Схема физически не умеет некоторых вещей:
- Не умеет отрицать. Нельзя нарисовать «здесь нет ретраев» или «этот сервис никогда не пишет в основную базу». Отсутствие стрелки читается как «автор забыл», а не как запрет. Всё запретительное — текстом.
- Не умеет выражать условие. «Только при включённом фичефлаге
new_pricing» на схеме превращается в подпись у стрелки, которую половина читателей не заметит. - Плохо выражает количество. «Раз в сутки», «до 5 минут лага», «p99 = 300 мс» на схеме занимают столько же места, сколько и в тексте, но хуже ищутся.
- Не умеет объяснять «почему». Причины решения — жанр ADR, и никакая картинка их не заменит.
Что схема делает лучше прозы:
- Топология: кто с кем связан, что через что проходит, где границы владения.
- Одновременность и порядок во времени: кто кого ждёт, что параллельно, где таймаут.
- Вложенность и границы: что внутри процесса, что внутри сети, что внутри команды.
- Циклы и тупики: обратные рёбра, из которых видно потенциальный дедлок или бесконечный ретрай, — текстом это почти нечитаемо.
Простое правило выбора формы, которое экономит много времени:
| Что вы описываете | Форма |
|---|---|
| Набор однотипных фактов с одинаковыми полями | таблица |
| Последовательность шагов, которые читатель выполняет руками | нумерованный список |
| Ветвление процедуры с 2–5 развилками | текст со списком или flowchart |
| Кто с кем связан, много связей n:m | схема |
| Порядок сообщений во времени, кто чего ждёт | sequenceDiagram |
| Разрешённые переходы объекта между состояниями | stateDiagram-v2 |
| Сущности и кардинальности | erDiagram |
| Почему выбрали так, а не иначе | проза |
подпись-утверждение?"} B -->|"нет"| Z["Не рисовать:
сообщения пока нет"] B -->|"да"| C{"Утверждение про отношения
между объектами?"} C -->|"нет, про условия,
причины и числа"| T["Текст или таблица"] C -->|"да"| D{"Объектов больше 9?"} D -->|"да"| E["Разбить: обзорная схема
+ детальные по ссылкам"] D -->|"нет"| F{"Предмет меняется чаще,
чем раз в квартал?"} F -->|"да"| G["Генерировать из кода
или не заводить"] F -->|"нет"| H["Рисовать руками:
исходник в репозиторий,
владелец и дата в подписи"] E --> F
Отдельно про соблазн: схема субъективно ощущается как «более серьёзная работа», чем абзац. Нарисовать четыре коробки — приятно, это видимый результат. Написать три точных предложения тяжелее и выглядит скромнее. Этот перекос стоит держать в голове: значительная часть схем в корпоративных вики появилась не потому, что текст не справлялся, а потому, что рисовать было интереснее, чем формулировать.
Три разбора: плохая версия и переписанная
Разбор 1: абзац, который должен был стать схемой
Плохо — реальный по духу кусок из RFC про интеграцию с эквайрингом:
Клиент отправляет запрос на создание платежа, при этом если в течение 2 секунд ответ от антифрода не получен, запрос всё равно уходит в банк, но с пометкой, и после ответа банка сервис публикует событие, которое читает нотификатор и отчётность, при этом отчётность может прочитать событие раньше, чем транзакция станет видна в реплике, поэтому там сделана задержка, а нотификатор ретраит, если получил 5xx, до трёх раз с экспоненциальной паузой, что в худшем случае даёт около 14 секунд, и всё это время статус в API остаётся
pending.
Одно предложение на 80 слов, шесть участников, три временных условия. Читатель RFC должен решить: безопасно ли его сервису опрашивать статус раз в секунду. Чтобы ответить, он вынужден трижды перечитать абзац и нарисовать себе картинку на бумаге. Это тот случай, когда автор переложил свою работу на читателя — см. ясность.
Переписано — три предложения плюс схема:
Путь платежа занимает до 14 секунд в худшем случае, и всё это время API отдаёт
pending. Антифрод не блокирует: после 2 секунд запрос уходит в банк с пометкойfraud_unknown. Отчётность намеренно отстаёт от события на 5 секунд, чтобы дождаться реплики.
Что стало видно и чего не было в тексте: F--xP — потерянный ответ, а не отказ; параллельность
двух потребителей события; то, что «14 секунд» набегают на ветке нотификатора, а не на пути
клиента. Читатель отвечает на свой вопрос за пять секунд.
Обратите внимание: текст не исчез. Схема сняла с него топологию и время, а условия, числа и слово «намеренно» остались в прозе. Хорошая пара «текст + схема» не дублирует друг друга.
Разбор 2: схема, которая должна была стать таблицей
Плохо: flowchart из двенадцати прямоугольников, каждый — параметр конфигурации ретраев,
со стрелками «влияет на». Автор потратил час на раскладку, читатель видит спагетти.
Признак диагноза простой: если у всех узлов схемы одинаковый набор атрибутов и связи между ними однотипные — это таблица, которую зачем-то нарисовали. Схема оправдана, когда связи разнородны и важна их конфигурация.
Переписано:
| Параметр | Значение по умолчанию | Кто меняет | Эффект при увеличении |
|---|---|---|---|
retry.max_attempts |
3 | владелец сервиса | дольше держим соединение, выше шанс дубля |
retry.base_delay |
1 с | владелец сервиса | мягче к бэкенду, дольше суммарное время |
retry.jitter |
0.3 | не меняем | защита от синхронного шторма |
timeout.request |
2 с | согласовать с SRE | больше висящих запросов в пуле |
Читатель ищет строку и находит. Ни одна стрелка ему не нужна.
Разбор 3: «архитектура», нарисованная и переписанная
Вот примерно та схема из вступления — упрощённая, но с сохранением всех пороков:
Что здесь не так:
- Стрелки означают разное.
PAY --> DB— это запись,PAY --> AF— синхронный вызов,PAY --> NOTIF— публикация события,LOG --> PAY— вообще ничего: логи не вызывают сервис, автор имел в виду «сервис пишет логи», но нарисовал наоборот. Одна фигура, четыре смысла. - Смешаны уровни.
Redisи «БД» — инфраструктура,API Gateway— контейнер,Пользователь— внешний актор,Логи— вообще не элемент архитектуры. - Нет утверждения. Из схемы нельзя вынести ни одного факта, который поменял бы решение.
- Названия не совпадают с реальностью. В деплое сервис называется
payments, в схеме —payments-api; «БД» — это на самом деле два кластера Postgres.
Переписано под конкретный вопрос дежурного «какие зависимости на пути пользователя синхронные»:
лаг до 5 мин"| RPL[("pg-replica")] R --> RPL
Изменилось: сплошная стрелка — синхронный вызов с таймаутом, пунктир — асинхронная передача, у каждой стрелки подписан протокол и бюджет времени, границей выделено то, что на самом деле влияет на доступность оплаты, узлов пять вместо четырнадцати, имена совпадают с деплоем. Подпись: «На пути пользователя ровно три синхронных участника; antifraud настроен fail-open и его падение оплату не роняет». Дежурный из вступления с такой схемой не потерял бы двадцать пять минут.
Стрелка — самая перегруженная фигура в инженерной графике
В одном и том же документе стрелка регулярно означает:
- синхронный вызов (кто кого зовёт);
- поток данных (куда что течёт — иногда против направления вызова: HTTP GET зовёт вправо, данные идут влево);
- зависимость сборки (
Aне компилируется безB); - наследование или реализацию (в UML это отдельная фигура, в рисовалках — та же стрелка);
- переход между состояниями;
- временную последовательность («сначала это, потом то»);
- владение («команда владеет сервисом»).
Три правила, которые снимают почти все двусмысленности:
- Одна схема — одна семантика стрелки. Если нужны две, они должны отличаться визуально (сплошная/пунктир) и обе объяснены в легенде.
- Направление фиксируется явно. «Стрелка от вызывающего к вызываемому» и «стрелка
по направлению данных» — оба соглашения нормальны, но их нельзя смешивать и нужно
назвать в легенде. Ошибка направления в графе зависимостей — классика:
A → Bможет означать и «A зависит от B», и «B зависит от A», и на схеме модулей это меняет вывод на противоположный. - Подпись у стрелки говорит о механизме, а не о намерении. Не «отправляет уведомление»,
а «Kafka:
payment.settled». Механизм проверяем, намерение — нет.
Про имена узлов: они должны совпадать с тем, что человек увидит в дашборде, в логах и в
kubectl get deploy. Схема, где сервис назван «Модуль расчёта скидок», а в кластере он
pricing-worker, заставляет читателя делать лишний перевод — и в три часа ночи он его
не сделает. Это та же дисциплина именования, что в документации API:
одно понятие — одно имя во всех артефактах.
Сколько узлов выдерживает схема
Кратковременная память удерживает около четырёх независимых элементов — оценка Нельсона Кауэна, уточняющая знаменитые «семь плюс-минус два» Джорджа Миллера (https://doi.org/10.1017/S0140525X01003922). Схема отчасти снимает это ограничение: она внешняя память, глазу не нужно всё удерживать. Но связи всё равно приходится прослеживать по одной.
Рабочая эвристика: 9 узлов и 12 рёбер — верхняя граница для схемы в документе. Дальше чтение превращается в поиск по лабиринту. Если объектов больше — это не «одна подробная схема», а несколько схем разного уровня.
Вторая проверка, ещё грубее: 30 секунд. Покажите схему коллеге, который не в контексте, и через полминуты спросите, что он понял. Если он пересказывает вашу подпись-утверждение — схема работает. Если начинает описывать коробки («ну, тут вот платежи, тут база…») — она не сообщила ничего.
Честная оговорка: карты на сорок узлов бывают полезны — как справочник по территории, для планирования миграции, для разговора о зонах владения. Но это отдельный жанр, ближе к системному анализу, и в документе, который должен изменить решение, такой карте не место. Дайте на неё ссылку.
Уровень абстракции: главная причина, по которой схемы не читают
Самый частый дефект — смешение уровней: рядом стоят «Kubernetes-кластер», «класс
OrderValidator» и «Отдел биллинга». Читатель не понимает, на каком масштабе он находится,
и не может решить, полна ли схема: если тут есть один класс, где остальные?
Общепринятый способ навести порядок — модель C4 Саймона Брауна (https://c4model.com/): четыре уровня зума, на каждом свой читатель. Плюс важное свойство, которое из самой модели не следует, но всегда наблюдается на практике: чем ниже уровень, тем быстрее схема протухает.
Практические выводы из этой картинки:
- C1 и C2 пишут руками и они окупаются. Контекст меняется, когда меняется бизнес; контейнеры — когда меняется деплой, то есть несколько раз в год. Такую схему можно вести вручную и раз в полгода сверять.
- C3 и ниже руками вести нельзя. Модули внутри сервиса меняются каждый спринт. Либо
генерируйте (
madge,jdeps,go mod graph,pydeps,dependency-cruiser), либо не заводите вовсе — читатель всё равно откроет код. - На одной схеме — один уровень. Переход вниз делается ссылкой, а не увеличением детализации в углу.
Есть и обратный отбор: схема тем долговечнее, чем меньше на ней конкретики. Схема из трёх кругов «клиент — наша система — банк» проживёт пять лет и почти ничего не сообщит. Полезность и срок жизни — обмен, и его стоит делать осознанно, а не случайно.
Соседние нотации, которые здесь уместно знать и не изобретать заново: UML — когда нужна строгость и читатели её знают; BPMN — для бизнес-процессов с ролями и дорожками; карты контекстов из DDD — для отношений между командами и моделями. Полная строгость UML в инженерном документе чаще мешает: половина читателей не различает агрегацию и композицию, и вы получаете точность, которую никто не считывает.
Анатомия схемы, которую можно поддерживать
Пять частей, и все пять обязательны:
- Заголовок-утверждение — что читатель должен унести.
- Тело — не больше девяти узлов одного уровня, имена как в деплое.
- Легенда — если фигур или типов стрелок больше одного. Три строки, не таблица.
- Метаданные под картинкой — уровень, владелец (
@team-payments), путь к исходнику в репозитории, дата последней сверки и дата следующей. - Текстовое резюме — два-три предложения рядом, которые сообщают то же самое словами.
Пятый пункт кажется избыточным, но он делает сразу три вещи: работает для тех, кто читает скринридером, спасает, когда картинка не отрендерилась (а она не рендерится в письмах, в некоторых мессенджерах и в PDF-выгрузках), и ловится полнотекстовым поиском — по картинке искать нельзя, и схема, о которой знает только тот, кто её видел, для организации не существует.
Как схему увидят на самом деле
Автор смотрит на схему в редакторе на 27-дюймовом мониторе. Читатель видит её:
- на телефоне шириной 390 точек — половина схем становится нечитаемой полосой;
- в тёмной теме — светлые заливки выжигают глаза, а чёрный текст на тёмном фоне исчезает;
- в чёрно-белой печати или в скриншоте, пересланном в чат;
- глазами человека с дейтеранопией — это около 8% мужчин, и красно-зелёное различение у него не работает.
Отсюда набор технических требований, которые дешевле соблюсти сразу:
- Цвет не должен быть единственным носителем смысла. Различайте сплошной/пунктирной линией, формой, подписью. Цвет — усиление, а не код. Подробнее — визуальная доступность.
- Контраст текста на схеме — не ниже 4.5:1, линий и границ — не ниже 3:1.
- Средние тона вместо чистого чёрного и чистого белого: тогда схема выживает и в светлой, и в тёмной теме.
- Шрифт на схеме не мельче основного текста. Если подписи не помещаются — на схеме слишком много узлов, а не «нужен шрифт помельче».
- Альтернативный текст описывает вывод, а не перечисляет фигуры. Плохо: «схема с пятью прямоугольниками и стрелками». Хорошо: «на пути пользователя три синхронных сервиса; notifier и reporting подписаны на Kafka и на доступность оплаты не влияют». Как это читается вслух — см. скринридеры.
- Никаких фотографий доски и скриншотов из Figma. Их нельзя ни поправить, ни найти поиском, ни отдиффать.
Diagram-as-code: почему исходник схемы обязан быть текстом
Ключевое отличие текстового источника от рисовалки — не удобство, а включённость в тот же
процесс, что и код: diff, ревью, ветка, откат, генерация в CI. Схема, лежащая как .png,
не может участвовать в ревью — рецензент видит «изменился бинарный файл» и жмёт «одобрить».
Про то, как это встроено в совместную работу, — коллаборация в git.
| Инструмент | Где силён | Где ломается |
|---|---|---|
| Mermaid (https://mermaid.js.org/) | рендерится нативно в GitHub, GitLab, Obsidian, Hugo; нулевой порог входа | слабый контроль раскладки; на 15+ узлах получается каша |
| PlantUML (https://plantuml.com/ru/) | строгий UML, много типов, зрелость | нужен Java-рендерер или сервис; синтаксис многословен |
| Graphviz/DOT (https://graphviz.org/) | автораскладка больших графов, идеален для генерации | руками писать неприятно; раскладка «прыгает» между версиями |
| D2 (https://d2lang.com/) | приятный синтаксис, хорошая раскладка, темы | молодой, меньше интеграций |
| Structurizr DSL (https://structurizr.com/dsl) | одна модель — много представлений C4; проверяет консистентность | требует дисциплины и отдельной модели |
| Kroki (https://kroki.io/) | единый HTTP-фасад ко всем перечисленным | ещё один сервис в инфраструктуре |
| Excalidraw / draw.io / Figma | скорость на воркшопе, свобода раскладки | не диффятся, не ревьюятся, не генерируются |
Разумная позиция: текстовый источник для всего, что живёт в репозитории; рисовалка — для одноразового наброска в обсуждении. Набросок из чата, переживший обсуждение, перерисовывается в текст — или умирает, и это нормально.
Отдельно про раскладку. Автораскладка почти всегда хуже ручной по читаемости и почти всегда
лучше по стоимости владения. Компромисс — фиксировать порядок узлов и направление
(flowchart LR, direction, подграфы), но не бороться за пиксели: следующая версия
рендерера всё равно всё сдвинет.
Почему схемы устаревают быстрее текста
Общая механика гниения документации — тема следующей главы. Но у схем есть три собственных усилителя, из-за которых они протухают первыми.
Первое: схема почти всегда конкретна. Текст можно написать инвариантно — «оплата проходит через антифрод, который настроен не блокировать при недоступности» верно, пока верна политика, даже если сервис переименовали. Схема же состоит из имён и связей, то есть ровно из того, что меняется при каждом рефакторинге.
Второе: у схемы нет тестов. Код примера из руководства можно прогнать в CI, и он покраснеет. Стрелка между двумя коробками не краснеет никогда: она остаётся ровной и убедительной и через два года после того, как связи не стало.
Третье: схему дороже поправить, чем текст. Абзац правится за минуту в том же PR. Картинку надо открыть в редакторе, найти исходник (если он есть), не сломать раскладку, переэкспортировать, приложить. Стоимость правки выше — значит, правки не будет.
Обратите внимание, где именно ломается цепочка: не в момент «люди забыли обновить», а в момент, когда изменение системы и изменение схемы оказались в разных задачах. Всё остальное — следствие.
Что с этим делают структурно
Призыв «обновляйте схемы» не работает — он не меняет ни одного стимула. Работают пять рычагов, и все они про устройство процесса, а не про добросовестность.
1. Близость к коду
Исходник схемы лежит в репозитории того сервиса, который она описывает, а не в общей вики:
services/payments/docs/c2.mmd. Тогда изменение архитектуры и изменение схемы попадают
в один PR, и рецензент видит расхождение. Правило «схема, описывающая один сервис, живёт
в этом сервисе; схема, описывающая связи трёх, живёт там, где владелец интеграции» решает
90% споров о том, куда класть.
Эффект «расстояния» здесь тот же, что для текста вообще: чем дальше документ от изменяемого кода, тем быстрее расхождение. Общая механика — в главе о поддержке.
2. Генерация — но с фильтром
Что реально генерируется сегодня:
# Граф модулей Go — источник правды сам код
go mod graph | grep '^github.com/acme/payments' > docs/generated/modgraph.txt
# Граф импортов JS/TS: только слой домена, иначе получится ковёр из 400 узлов
npx madge --extensions ts --image docs/generated/domain-deps.svg src/domain
# Terraform: что реально развёрнуто, а не что мы думаем
terraform graph -type=plan | dot -Tsvg > docs/generated/infra.svg
# C4 из модели: одна модель — несколько согласованных представлений
structurizr-cli export -workspace docs/arch/workspace.dsl -format mermaid
Плюс то, что генерируется само и часто недооценено: карта сервисов из распределённой трассировки. Jaeger и Tempo строят граф реальных вызовов по трафику — это единственная схема, которая по определению не врёт, потому что показывает то, что происходило вчера (см. наблюдаемость). ER-диаграмму базы можно вывести из миграций, схему API — из OpenAPI.
Честное ограничение: сгенерированная схема почти всегда нечитаема без фильтра. Граф зависимостей на 400 узлов — не документ, а обои. Правило: генерируйте не «всё», а подмножество, заданное явно (один слой, одна доменная область, глубина 1). Тогда получается и правда, и читаемость.
3. Владелец и срок годности
Схема без владельца — это схема, которую никто не поправит. Минимальный набор:
# docs/arch/c2-payments.meta.yaml
title: "Синхронные зависимости на пути оплаты"
level: C2
owner: "@team-payments"
source: "services/payments/docs/c2.mmd"
verified_at: 2026-06-14
review_by: 2026-12-14
lifetime: living # living | frozen | scratch
Плюс строка в CODEOWNERS, чтобы изменение схемы всегда приезжало к нужной команде:
services/payments/docs/ @acme/team-payments
docs/arch/ @acme/architecture-guild
4. Срок жизни как жанр
Три класса схем, с разными правилами. Путаница между ними — источник большей части мусора.
| Класс | Где живёт | Что с ней делают | Признак нарушения |
|---|---|---|---|
Одноразовая (scratch) |
тред обсуждения, PR, доска | не обновляют, не переносят в вики | набросок из чата, скопированный в вики «чтобы не потерялся» |
Замороженная (frozen) |
внутри ADR или постмортема | никогда не обновляют: она документ о прошлом | кто-то «актуализировал» схему в ADR трёхлетней давности |
Живая (living) |
README сервиса, справочник | обновляют в том же PR или генерируют | живая схема без владельца и без даты |
Отсюда самое полезное правило главы:
Живую схему делай генерируемой — или не делай живой. Всё остальное превращается в замороженную схему, которая притворяется живой, и это худший из трёх вариантов: читатель ей верит.
Схема в ADR замораживается вместе с решением и правится только новым ADR — ровно так же, как сам текст решения. Схема в постмортеме показывает систему на момент инцидента, и «исправлять» её задним числом означает уничтожать свидетельство (см. постмортемы в SRE).
5. Проверки в CI
Схема не проверяется на истинность автоматически, но кое-что проверить можно — и это ловит большую часть тихой лжи:
# .github/workflows/diagrams.yml — фрагмент
- name: Схемы рендерятся
run: npx @mermaid-js/mermaid-cli -i docs/arch/c2.mmd -o /tmp/c2.svg
- name: Имена узлов существуют в реестре сервисов
run: python scripts/check_nodes.py docs/arch/*.mmd --registry catalog/services.yaml
- name: Метаданные на месте и срок не истёк
run: python scripts/check_meta.py docs/arch/*.meta.yaml --max-age-days 180
- name: Ссылки в подписях живы
run: lychee --no-progress docs/arch/
Проверка имён узлов по реестру сервисов — самая недооценённая: она ловит переименования
и удаления, то есть именно те изменения, из-за которых схема начинает врать молча. Если
у вас есть каталог сервисов (Backstage или самописный services.yaml), эта проверка пишется
за час и работает годами. О том, как встраивать такие каталоги, —
внутренняя платформа.
Схемы, которые рисуют ради процесса, а не ради читателя
Часть схем в вашей организации существует не для того, чтобы кто-то что-то понял. Они существуют, потому что в шаблоне проектного документа есть раздел «Архитектурная схема», и без заполненного раздела документ не пройдёт комитет. Это не заговор и не глупость: у крупной организации нет способа проверить качество мышления в двухстах документах, и она проверяет наличие артефактов. Об экономике этого явления — в работе вверх.
Признаки, по которым такая схема опознаётся:
- На неё никто не задаёт вопросов. Настоящая схема провоцирует спор: «а почему тут синхронно?». Обрядовая — тишину.
- Её не открывали во время инцидента. Проверяется по метрикам вики или по тому, что дежурные о ней не знают.
- История файла — один коммит.
git log --followпоказывает создание и ноль правок за два года, хотя система менялась. - Её нельзя изменить без согласования, но можно не сверять с реальностью — верный признак, что охраняют форму, а не содержание.
- Она объясняет систему тому, кто не будет принимать по ней решений — «схема для руководства», которую руководство не открывает.
- Её рисовали после того, как всё построили. Схема, появившаяся через месяц после релиза, документирует не решение, а факт.
Проверка в одну фразу: спросите, какое решение и кем было принято по этой схеме за последний год. Если ответа нет — это артефакт процесса.
Что с этим делать. Воевать с шаблоном обычно бесполезно и дорого. Рабочая стратегия — разделить два документа и по-разному распределить усилия:
- Обрядовую схему делайте дёшево и честно: минимальный C1, сгенерированный или собранный за двадцать минут, с явной пометкой «обзорная схема для согласования; рабочая схема сервиса — вот здесь, ссылка». Не вкладывайте в неё вечер.
- Рабочую схему держите рядом с кодом, в живом жанре, под владельцем. Именно она сокращает время инцидента и онбординга.
- Не смешивайте: обрядовая схема в вики, которую все считают рабочей, — тот самый худший случай из прошлого раздела.
Иногда получается изменить и сам шаблон. Аргумент, который работает лучше всего, — не «схемы бесполезны», а измеримый: «за год по схеме из раздела 4 не было принято ни одного решения; предлагаю заменить обязательную схему на обязательную ссылку на живую схему сервиса». Это разговор про регламент, а не про вкус, и его стоит вести с данными — как в переговорах про процесс.
Схема на доске — другой жанр
Всё вышесказанное про схемы в документах. Схема, которую рисуют вживую при обсуждении, — инструмент мышления, и правила у неё противоположные: она обязана быть черновой, её ценность в том, что её меняют по ходу разговора, и умереть она должна вместе с встречей.
Два практических следствия:
- Рисуйте на доске, пока спорите. Половина архитектурных споров — спор о разных картинках в головах, и он снимается за две минуты, как только обе картинки нарисованы. Систематизированная версия этой практики — event storming.
- Фотография доски — не документ. После встречи из наброска рождается либо схема в текстовом источнике с подписью-утверждением, либо ничего. Фото в вики — это способ сделать вид, что решение задокументировано.
Похоже устроен и разбор инцидента: схема, нарисованная во время реагирования, одноразовая; в постмортем попадает переработанная и замороженная.
Мелкий, но частый случай: схема данных
erDiagram — редкий тип, где картинка почти всегда лучше прозы, потому что кардинальности
текстом читаются отвратительно. Сравните: «у пользователя может быть несколько платёжных
методов, каждый платёж ссылается ровно на один метод, но метод может быть удалён, и тогда
платёж хранит снимок» — и:
Схема сообщает кардинальности мгновенно. Но заметьте, чего она не сообщает: что снимок нужен именно из-за удаления метода. Причина остаётся текстом — одно предложение под картинкой. Подробнее про моделирование — модель данных.
Чек-лист перед тем, как вставить схему
- Я могу написать под ней подпись-утверждение в одно предложение.
- Я знаю, кто читатель и какое решение он принимает, глядя на неё.
- Это не таблица и не список, которые зачем-то нарисованы.
- Один уровень абстракции; узлов не больше девяти.
- У всех стрелок одна семантика либо есть легенда.
- Имена узлов совпадают с деплоем, логами и дашбордами.
- Условия, числа и причины остались в тексте, а не уехали в подписи у стрелок.
- Исходник текстовый и лежит в репозитории; в подписи есть путь к нему.
- Указаны владелец, дата сверки и класс: одноразовая / замороженная / живая.
- Если живая — либо генерируется, либо у неё есть человек и дата пересмотра.
- Есть текстовое резюме рядом: для поиска, для скринридера, для несработавшего рендера.
- Читаема на телефоне, в тёмной теме и в чёрно-белой печати.
Частые ошибки
- Схема вместо мысли. Нарисовали коробки, а решение так и не сформулировали.
- Схема-инвентаризация. Всё, что есть в системе, на одном листе — «чтобы было полно».
- Стрелки-омонимы. Четыре разных смысла одной фигурой, легенды нет.
- Стрелка не в ту сторону в графе зависимостей — вывод читателя становится обратным.
- Смешанные уровни. Кластер, класс и отдел на одной картинке.
- Схема как единственный носитель факта. Важное условие есть только в подписи у стрелки — и не находится поиском.
- Фото доски / скриншот Figma вместо исходника.
- Живая схема без владельца. Формально актуальна, фактически трёхлетней давности.
- «Актуализация» замороженной схемы в ADR или постмортеме — уничтожение свидетельства.
- Генерация без фильтра. Правдивые обои из четырёхсот узлов.
- Цвет как единственный код — не работает в печати и у части читателей.
- Схема, дублирующая соседний абзац слово в слово: два источника правды вместо одного.
Практика
- Найдите самую популярную схему в вашей вики. Напишите под ней подпись-утверждение. Если не получается — вы нашли схему-инвентаризацию; предложите заменить её тремя схемами под три конкретных вопроса.
- Возьмите свой последний RFC или ADR. Найдите абзац длиннее шестидесяти слов,
описывающий взаимодействие во времени. Перепишите: три предложения +
sequenceDiagram. Сравните, сколько вопросов задали на ревью до и после. - Проведите тест 30 секунд на трёх коллегах вне контекста. Записывайте не «понял/ не понял», а что именно они пересказывают.
- Проверьте историю.
git log --followпо файлу схемы и по коду сервиса за год. Если схема правилась в десять раз реже — оцените, какие именно стрелки уже неверны. - Заведите один живой C2 для своего сервиса:
.mmdв репозитории, метаданные, владелец, рендер в CI, ссылка из README. Через квартал посмотрите, правился ли он вместе с кодом — это и есть проверка того, что близость к коду работает. - Найдите обрядовую схему по шести признакам из соответствующего раздела. Сформулируйте предложение по замене в терминах регламента, а не вкуса.
Источники
- Simon Brown. The C4 model for visualising software architecture — https://c4model.com/; книга Software Architecture for Developers — https://leanpub.com/b/software-architecture
- Structurizr DSL — https://structurizr.com/dsl; Mermaid — https://mermaid.js.org/; D2 — https://d2lang.com/; PlantUML — https://plantuml.com/ru/; Graphviz — https://graphviz.org/; Kroki — https://kroki.io/
- Edward R. Tufte. The Visual Display of Quantitative Information, 2nd ed. Graphics Press, 2001 — https://www.edwardtufte.com/book/the-visual-display-of-quantitative-information/
- Colin Ware. Information Visualization: Perception for Design, 4th ed. Morgan Kaufmann, 2020 — https://www.sciencedirect.com/book/9780128128756/information-visualization
- Nelson Cowan. The magical number 4 in short-term memory — https://doi.org/10.1017/S0140525X01003922
- Diátaxis — https://diataxis.fr/ (где схема уместна в каждом из жанров документации)
- Google developer documentation style guide, раздел про изображения — https://developers.google.com/style/images
- WCAG 2.2, критерии 1.1.1 (нетекстовый контент) и 1.4.11 (контраст нетекстовых элементов) — https://www.w3.org/TR/WCAG22/
- Backstage как реестр сервисов, по которому можно проверять имена узлов — https://backstage.io/docs/features/software-catalog/
- arc42 — шаблон архитектурной документации с явными уровнями представлений — https://arc42.org/overview
Что дальше
Мы всё время упирались в одно: схема протухает не потому, что автор ленив, а потому, что изменение системы и изменение документа лежат в разных задачах, у разных людей и с разной стоимостью. То же самое верно для текста — просто медленнее и незаметнее. Следующая глава разбирает эту механику целиком: почему документация устаревает, какие структурные меры действительно работают — близость к коду, генерация, владелец, срок жизни, проверки — и как понять, какие документы вообще стоит поддерживать, а какие честнее удалить.
Почему документация устаревает и что с этим делать структурно