Когда мы начали создавать платформу True Engineering, в компании не было единых правил для оформления архитектуры. Разные команды – разные инструменты, разные обозначения и уровни абстракции. Значит, даже подобные решения сравнить между собой не получится, а тому, кто смотрит на архитектуру проекта в первый раз, обычно нужен проводник, который расскажет, что же тут изображено. Мы решили унифицировать подходы с помощью модели С4, которая обеспечивает всестороннее описание программных архитектур.
Сама по себе такая задача описания архитектуры, мягко говоря, не новая, и решить её можно несколькими способами:
MS Visio и подобные редакторы – громоздко, малоудобно. Эти средства создавались для иных целей, и это заметно.
UML – эти диаграммы быстро увеличиваются в количестве, довольно скоро их становится сложно поддерживать. К тому же фактически нужно всегда иметь в виду масштаб всей системы.
4+1 – снова проблемы с поддержкой и масштабом, высокий порог входа для новых участников команды.
В C4 многих этих проблем нет. Она объединяет 4 иерархических уровня: (1) Context, (2) Container, (3) Component, (4) Code.
Как можно прочитать на сайте по модели C4, создал её лондонский программный архитектор Саймон Браун (Simon Brown) в рамках своего учебного курса. В программе было упражнение, когда участников просили разработать архитектуру продукта по заданным требованиям. Браун увидел, что нарисовать несколько диаграмм, чтобы выразить замысел, оказалось сложнее, нежели он представлял. И разработал систему для формализованного подхода к архитектуре ПО.
Зачем создали модель C4
Чтобы помочь командам описывать архитектуру как при предварительном проектирования, так и при ретроспективном документировании кодовой базы
Чтобы создавать карты кода на разных уровнях детализации – автор приводит в пример Google Maps, где можно увидеть целые страны, прежде чем опуститься до области, города и отдельного дома.
Чтобы дать архитекторам, разработчикам, PM-ам и аналитикам абстрактные модели для работы с архитектурным схемами.
Теперь о том, что это за абстракции и на каких уровнях они существуют.
Уровень 1. Диаграмма системного контекста (System Context) обеспечивает отправную точку, которая показывает, как программная система вписывается в окружающий ее мир.
Здесь описываются функции, которые приносят пользу пользователям. Уровень включает в себя и сам продукт, и другие взаимосвязанные с ними системы.
Детали здесь не важны, так как это уменьшенное изображение, показывающее общую картину системного ландшафта. В центре внимания не технологии, протоколы и другие низкоуровневые детали, а пользователи, роли, акторы, программные системы. С этой диаграммой будет легко работать бизнес-заказчикам и не-техническим людям.
Уровень 2: Как только вы поймете, как ваша система вписывается в общую ИТ-среду, следующий шаг - увеличить масштаб до высокоуровневых строительных блоков. Диаграмма контейнера (Container) показывает общую форму архитектуры, распределение функций и обязанностей.
Не путать с Docker-контейнерами – в C4 контейнер представляет то, что необходимо запустить для работы всего продукта. Например, серверное, мобильное или веб-приложение, клиентская программа, БД, бессерверная функция, shell-скрипт.
Каждый контейнер – это отдельно развертываемый объект или среда выполнения, которая зачастую работает в собственном пространстве процессов. Из-за этого связь между контейнерами обычно принимает форму межпроцессного взаимодействия.
Такая диаграмма полезна как команде разработчиков, так и службе поддержки.
Уровень 3. Диаграмма компонентов (Component) показывает устройство контейнера.
В этом контексте компонент - это группа связанных функций, объединённых четко определенным интерфейсом. В Java или C#, например, это набор классов реализации, стоящих за интерфейсом. Все компоненты не являются отдельно развертываемыми единицами и обычно выполняются внутри контейнера в одном и том же пространстве процесса.
Архитекторы и разработчики видят, из чего состоит каждый контейнер, что представляет собой каждый из компонентов, их обязанности и детали реализации. Другим участникам команды такая диаграмма вряд ли понадобится – их стоит готовить, только если их ценность очевидна. Желательно подумать об автоматизации для долговременной документации.
Уровень 4. Диаграмму кода (Code), например, класс UML, можно использовать для изучения отдельных модулей. Не рекомендуется ни для чего, кроме наиболее важных или сложных компонентов.
Это дополнительный уровень детализации, который в идеале нужно генерировать автоматически с использованием IDE, UML и других инструментов. Следует рассмотреть возможность отображения только тех атрибутов и методов, которые могут показать на практике некую историю.
Даже с относительно небольшой программной системой заманчиво попытаться включить всю историю в одну диаграмму. На практике вам, скорее всего, не хватит места на холсте или информацию загромоздит множество перекрывающихся линий. Если никто не поймет диаграмму, никто не будет ее смотреть.
Вместо этого стоит попробовать разделить сложную диаграмму на простые по определенным областям бизнеса, функциям, контексту, взаимодействию с пользователем и т.д.
Рабочие инструменты
Чтобы создать такую модель, мы используем следующий стек:
PlantUML – позволяет генерировать UML-диаграммы из текста;
C4Builder – обеспечивает экспорт в PDF и прочие форматы;
IDE-плагин – отвечает за автоматизацию и удобное для разработчиков взаимодействие с моделью.
Вот как выглядит рабочее окно IDE c возможностью переходить с одного уровня архитектурной абстракции на другой:
Как быстро устаревают диаграммы в C4
Из-за иерархической природы каждая диаграмма будет изменяться с разной скоростью.
Контекст системы: в большинстве случаев очень медленно, поскольку описывает ландшафт, в котором работает система.
Контейнеры: обновляется тем чаще, чем больше вы используете микросервисы, бессерверные функции и т.д.
Компоненты. Для любой системы в активной разработке, диаграммы компонентов будут меняться по мере того, как команда добавляет, удаляет или реструктурирует код. Как мы говорили, этот уровень стоит максимально автоматизировать.
Код: диаграммы, например, классов потенциально устареют очень быстро. По этой причине рекомендуется (1) не создавать их вообще или (2) создавать их по запросу с использованием таких инструментов, как ваша IDE.
YBogomolov
Регулярно использую диаграммы уровней C1 и C2, рисую в draw.io. Очень хорошо помогает быстро структурировать мысли при работе над архитектурой и доносить решения до команды. Что мне нравится в модели C4 — в отличии от совсем неформальной нотации boxes and lines она содержит ровно ту степень формализма, чтобы можно было ограничивать мышление нужным уровнем детализации и не скатываться в ошибочное описание всего архитектурного ландшафта в одной диаграмме, но при этом C4 достаточно либеральна и позволяет вольности — скажем, я люблю выделять зеленым цветом блоки, которые добавились в новой ревизии схемы, и красным те, которые будут удалены. Это позволяет диаграммы C4 вставлять в презентации или в вики «как есть», без лишней редактуры.