Хабр, привет!
Нас зовут Дмитрий Фролов и Владимир Мясников.
Мы стандартизировали подход по документированию внутренних систем в команде интеграционного тестирования Мир Plat.Form с помощью «Модели С4».
Платежная платформа «Мир» представляет из себя десятки систем и сотни интеграций, за работоспособность которых отвечает наша команда. Разобраться новичку, и даже опытному сотруднику, в происходящем бывает непросто, и сегодня мы расскажем, как помогаем коллегам быстро и удобно получать информацию о наших системах.
Давайте разберемся, что такое «Модель С4» и какие задачи она помогает решать. С чего начать, если вам поступила задача задокументировать «большую» систему – читайте под катом.
Дисклеймер
Все примеры, использованные в статье, намеренно сделаны непохожими на настоящую архитектуру платежной системы «Мир».
Что такое модель С4
Модель С4 – подход к моделированию архитектуры системы, в котором основной акцент нацелен на простоту нотации и различные уровни абстракции.
Простая и нестрогая нотация позволяет одинаково легко читать и моделировать диаграммы, а разные уровни абстракции подойдут как для бизнес-пользователей, так и для технических специалистов.
В документации к модели С4 подробно описано, как моделировать системы, а цель нашей статьи - рассказать, как мы на практике применяем модель С4 и поделиться накопленным опытом.
![Рисунок 1. Различные уровни абстракции для лучшего понимания архитектуры системы. Рисунок позаимствован с сайта https://c4model.com/. Рисунок 1. Различные уровни абстракции для лучшего понимания архитектуры системы. Рисунок позаимствован с сайта https://c4model.com/.](https://habrastorage.org/getpro/habr/upload_files/d6e/f75/7aa/d6ef757aafb46db0b42dde1d97ba0692.png)
Обзор уровней абстракции
Если вы уже знакомы с моделью С4, смело пропускайте этот раздел.
Уровень 1. Диаграмма контекста
Диаграмма контекста подходит для бизнес-пользователей, которым не нужно погружаться в технические нюансы.
Цели диаграммы – ответить на следующие вопросы:
Какие пользователи используют документируемую систему?
С какими системами взаимодействует документируемая система?
Для чего нужны взаимодействия с другими системами?
Легенда для диаграммы контекста
![Пользователь документируемой системы. Пользователь документируемой системы.](https://habrastorage.org/getpro/habr/upload_files/e53/cf3/ca7/e53cf3ca7c3e09d5c22f168653883d88.png)
![Документируемая система - высший уровень абстракции, описывающий нечто такое, что приносит пользу ее пользователям. Документируемая система - высший уровень абстракции, описывающий нечто такое, что приносит пользу ее пользователям.](https://habrastorage.org/getpro/habr/upload_files/3e3/d0c/243/3e3d0c24306b62eaadab7ec86414841d.png)
![Внешняя система, с которой взаимодействует документируемая система. Внешняя система, с которой взаимодействует документируемая система.](https://habrastorage.org/getpro/habr/upload_files/3ac/0e0/ae4/3ac0e0ae44fe3d7a28eb3c1eb8013ed9.png)
![Отношение между элементами диаграммы. Стрелка направлена от вызывающего к вызываемому. Отношение между элементами диаграммы. Стрелка направлена от вызывающего к вызываемому.](https://habrastorage.org/getpro/habr/upload_files/0ec/e6a/d1f/0ece6ad1f0155760f9674bef5e091156.png)
Уровень 2. Диаграмма контейнеров
Диаграмма контейнеров подходит для пользователей, которым нужно понять архитектуру приложения без глубокого погружения в техническую часть. Это наиболее полезная и обязательная абстракция при документировании системы.
Цели диаграммы – ответить на следующие вопросы:
Какие технологии использует система?
Из каких контейнеров состоит система?
Как контейнеры взаимодействую между собой?
Как контейнеры взаимодействую с внешними системами?
Как пользователи взаимодействуют с документируемой системой?
Легенда для диаграммы контейнеров
![Контейнер - некоторая самостоятельная часть системы, например «Мобильное приложение». Контейнер - некоторая самостоятельная часть системы, например «Мобильное приложение».](https://habrastorage.org/getpro/habr/upload_files/63c/251/4c5/63c2514c5e7101582e316649ad6d3fa3.png)
![Хранилище данных. Хранилище данных.](https://habrastorage.org/getpro/habr/upload_files/3c6/e0b/d29/3c6e0bd29aff32a08eef58a863d60815.png)
![Брокер или очередь сообщений. Брокер или очередь сообщений.](https://habrastorage.org/getpro/habr/upload_files/f4f/2af/1af/f4f2af1af637807828f9fd7849f3c06e.png)
![Группа контейнеров из которых состоит документируемая система. Группа контейнеров из которых состоит документируемая система.](https://habrastorage.org/getpro/habr/upload_files/f74/688/ff7/f74688ff79d0efcff33f2df2a7883ac8.png)
А также все элементы из «Диаграммы контекста».
Уровень 3. Диаграмма компонентов
Целевая аудитория этого уровня абстракции - программисты и архитекторы. Перед ее использованием рекомендуем посоветоваться с командой. Возможно, она вам не нужна.
Цели диаграммы – ответить на следующие вопросы:
Из каких компонентов состоит контейнер?
Как компоненты взаимодействуют между собой?
Как компоненты взаимодействуют с внешними системами?
Как пользователи взаимодействуют с компонентами?
Легенда для диаграммы компонентов
![Компонент - абстракция, из которых состоит контейнер. Компонент - абстракция, из которых состоит контейнер.](https://habrastorage.org/getpro/habr/upload_files/328/2a5/e32/3282a5e32b99f2af95a32402c1673f84.png)
![Хранилище данных. Хранилище данных.](https://habrastorage.org/getpro/habr/upload_files/3c6/e0b/d29/3c6e0bd29aff32a08eef58a863d60815.png)
![Брокер или очередь сообщений. Брокер или очередь сообщений.](https://habrastorage.org/getpro/habr/upload_files/f4f/2af/1af/f4f2af1af637807828f9fd7849f3c06e.png)
![Группа компонентов, из которых состоит контейнер. Группа компонентов, из которых состоит контейнер.](https://habrastorage.org/getpro/habr/upload_files/290/553/7f8/2905537f8a1292ed5056832ebdeb092a.png)
![Пользователь документируемой системы. Пользователь документируемой системы.](https://habrastorage.org/getpro/habr/upload_files/e53/cf3/ca7/e53cf3ca7c3e09d5c22f168653883d88.png)
![Внешняя система, с которой взаимодействует документируемая система. Внешняя система, с которой взаимодействует документируемая система.](https://habrastorage.org/getpro/habr/upload_files/3ac/0e0/ae4/3ac0e0ae44fe3d7a28eb3c1eb8013ed9.png)
![Отношение между элементами диаграммы. Стрелка направлена от вызывающего к вызываемому. Отношение между элементами диаграммы. Стрелка направлена от вызывающего к вызываемому.](https://habrastorage.org/getpro/habr/upload_files/0ec/e6a/d1f/0ece6ad1f0155760f9674bef5e091156.png)
Уровень 4. Диаграмма кода
Диаграмма кода используется для низкоуровневой детализации системы. На официальной странице модели С4 рекомендовано использовать UML Class diagram/Entity relationship diagram или схожие нотации.
Легенда для диаграммы кода
В рамках настоящей статьи мы не будем отдельно останавливаться на этих нотациях, так как это избыточно и выходит за границы модели С4.
Описываем свою первую систему
Работу по документированию системы следует начать с создания диаграммы контекста. Моделирование диаграммы контекста не представляет особых сложностей и не требует больших временных затрат.
Моделирование диаграммы контекста
В центре диаграммы размещаем элемент «Система»;
В верхней части диаграммы размещаем «Пользователей» системы;
По периметру «Системы» размещаем элементы «Внешняя система»;
Между элементами проводим стрелки от вызывающего к вызываемому. Внутри стрелок описываем какую функцию выполняет взаимодействие.
Расположение элементов не является обязательным, но мы внутри команды стараемся соблюдать единообразие. Этот комментарий относится ко всей статье.
![Рисунок 2. Пример диаграммы контекста. Рисунок 2. Пример диаграммы контекста.](https://habrastorage.org/getpro/habr/upload_files/d9b/e55/7da/d9be557da041d7032adec401814aa47a.png)
Моделирование диаграммы контейнеров
В центре схемы размещаем элемент «Пунктирную рамку»;
«Фронт-системы» вписываем в верхнюю часть прямоугольника, «Бэк-системы» вписываем в центре, «Хранилища данных» в самом низу рамки;
Над «Рамкой» размещаем «Пользователей» системы;
По периметру «Прямоугольной рамки» размещаем «Внешние системы»;
Стрелками описываем все интеграции и их технологии.
На этом уровне абстракции обычно очень много элементов, нужно постараться сделать схему небольшой и аккуратной.
![Рисунок 3. Пример диаграммы контейнеров. Рисунок 3. Пример диаграммы контейнеров.](https://habrastorage.org/getpro/habr/upload_files/9eb/6c3/124/9eb6c3124093d2d322b9f43cfc4fe04a.png)
Моделирование диаграммы компонентов
В центре схемы размещаем элемент «Пунктирную рамку»;
Внутри рамки размещаем «Компоненты», из которых состоит «Контейнер»;
Над «Рамкой» размещаем источники данных, в нижней части «Хранилища данных»;
По периметру рамки размещаем «Внешние системы» и «Контейнеры».
![Рисунок 4. Пример диаграммы компонентов. Рисунок 4. Пример диаграммы компонентов.](https://habrastorage.org/getpro/habr/upload_files/197/6fa/416/1976fa41647fa3c282767b163193ebcb.png)
Моделирование диаграммы кода
Моделировании в нотациях UML Class diagramm/Entity relationship diagram выходит за рамки нашей статьи, так как мы рассматриваем только С4. Таким образом, во избежание избыточности, мы пропустим этот раздел.
![Рисунок 5. Пример диаграммы кода (Entity relationship diagram в нотации Crow’s Foot). Рисунок 5. Пример диаграммы кода (Entity relationship diagram в нотации Crow’s Foot).](https://habrastorage.org/getpro/habr/upload_files/6ee/2e3/d9f/6ee2e3d9f5c20e304d454a3da1cd82ba.png)
Добавляем интерактивность
Для удобства навигации мы рекомендуем использовать интерактивные элементы. В этом разделе мы покажем свою реализацию на примере Confluence.
Создаем переход из «Диаграммы контекста» на «Диаграмму контейнеров», пример:
![Переход из диаграммы контекста в диаграмму контейнеров. Переход из диаграммы контекста в диаграмму контейнеров.](https://habrastorage.org/getpro/habr/upload_files/296/aeb/912/296aeb9120f6cce43ea35aa226985536.gif)
Создаем переход из «Диаграммы контейнеров» на «Диаграмму компонентов», пример:
![Переход из диаграммы контейнеров в диаграмму компонентов. Переход из диаграммы контейнеров в диаграмму компонентов.](https://habrastorage.org/getpro/habr/upload_files/cc0/00e/cd6/cc000ecd649a2c8ce98f812996b40e19.gif)
Создаем переход из «Диаграммы компонентов» на «Диаграмму кода». Для «Компонентов» следует использовать UML Class diagram, для «Хранилищ данных» следует использовать «Диаграмму базы данных» или «Entity-relationship diagram». Ниже пример с ER-моделью:
![Переход из диаграммы компонентов в ER-модель. Переход из диаграммы компонентов в ER-модель.](https://habrastorage.org/getpro/habr/upload_files/151/42f/e75/15142fe755eec4c477f5f7b939bda70b.gif)
Как мы адаптировали нотацию С4 для нужд команды
В этом разделе мы расскажем о некоторых ухищрениях и изменениях, которые помогают нам лучше выполнять работу в части интеграционного тестирования.
Используем единообразное расположение элементов:
Размещаем элемент «Пользователь» в верхней части диаграммы;
Размещаем «Хранилища данных» в нижней части диаграммы;
Размещаем «Внешние системы» по периметру, обычно слева и справа.
Стараемся делать небольшие диаграммы:
Стараемся чтобы диаграмма была размером А4, т.е. полностью умещалась на экран монитора или могла быть распечатана для обсуждения;
Если в диаграмме слишком много элементов, объединяем схожие элементы и декомпозируем на отдельной странице, как на примере ниже:
![Декомпозируем однотипные элементы на отдельной странице. Декомпозируем однотипные элементы на отдельной странице.](https://habrastorage.org/getpro/habr/upload_files/803/548/da2/803548da2aa52d12eed4264d01ded82a.gif)
Не используем диаграмму компонентов:
Мы приняли решение внутри команды, что для наших целей (Интеграционное тестирование) не требуется диаграмма компонентов, и мы не будем тратить на нее время.
Используем диаграмму последовательности:
Мы приняли решение использовать диаграмму последовательности вместо UML Class diagram/Entity relationship diagram для описания интеграций между системами:
![Описываем взаимодействие между системами с помощью диаграммы последовательности. Описываем взаимодействие между системами с помощью диаграммы последовательности.](https://habrastorage.org/getpro/habr/upload_files/e17/180/491/e17180491ec6df05ac726ca5e3283e13.gif)
Декомпозируем список интеграций:
Если между системами много интеграций, нет смысла проводить 5 отдельных стрелочек. Мы оформляем интеграции как 1 стрелку и декомпозируем их на отдельной странице:
![Декомпозируем интеграции на отдельной странице. Декомпозируем интеграции на отдельной странице.](https://habrastorage.org/getpro/habr/upload_files/1e1/972/453/1e197245331778fce66823fa20d5c2b5.gif)
Вывод
Наша команда работает с десятками систем, и модель С4 позволяет нам сэкономить время на чтение и поиск документации. Мы можем получить всю нужную информацию буквально в 3-4 клика.
Конечно, не бывает идеальных решений, и проблема нашего подхода - повышение человеко-часов на документацию и необходимость постоянно актуализировать диаграммы.
Ниже хотим вам показать итоговый пример, что должно получиться:
![Итоговый результат Итоговый результат](https://habrastorage.org/getpro/habr/upload_files/89a/b13/df6/89ab13df6640f116af4b9c48c19d8021.gif)
Мы верим, что наша статья поможет вам лучше работать с документацией и благодарим за чтение.