Нотация моделирования архитектуры С4 — примеры диаграмм и инструменты

от автора

Если возникает вопрос об описании архитектуры системы, то есть несколько основных решений где и как это сделать. Популярные нотации для визуализации схем архитектуры:

  • C4,

  • ArchiMate,

  • SysML,

  • 4+1,

  • AADL.

В этой статье я хочу сфокусироваться на нотации моделирования архитектуры C4. Моя цель — показать практические примеры её применения, который вы сможете использовать как ориентир в своей работе, а также инструменты для её создания.

В конце статьи я оставлю список источников, в которых можно будет посмотреть дополнительную теорию и примеры. 

Статья полезна для системных аналитиков, архитекторов, разработчиков, менеджеров проектов и тех, кто участвует в создании и принятии решений по организации архитектуры проекта.

Теория по нотации C4

Нотация моделирования C4 — это метод визуализации архитектуры программного обеспечения, разработанный Саймоном Брауном. Она используется для создания диаграмм, описывающих архитектуру систем.

C4 появилась как реакция на сложность и непонятность традиционных архитектурных диаграмм. Саймон Браун предложил этот подход в начале 2010-х годов с целью упростить понимание архитектуры для всех участников команды разработки, включая разработчиков, тестировщиков, аналитиков, менеджеров и других заинтересованных сторон.

Название «C4» расшифровывается как:

  • Context — Контекст, 

  • Containers — Конейнеры,

  • Components — Компоненты,

  • Code — Код.

Эти четыре «C» представляют четыре уровня абстракции (представления), которые используются в этой нотации для визуализации архитектуры.

Уровни представления архитектуры в нотации C4 в примерах

Краткое и наглядное описание для одного проета: схема C4 в Miro c примером проекта.

Для этой статьи визуализацию сделаю с помощью кода и инструмента https://www.structurizr.com/dsl.

? Context

Показывает, как система взаимодействует с внешними сущностями (пользователями, внешними системами). Сразу видно интеграции.

Обычно используют на начальных этапах проектирования, для понимания общего контекста.

Элементы:
— системы,
— пользователи,
— взаимосвязи.

Пример проекта:
Сервис-агрегатор
GetDelivery из моего канала для системных аналитиков, где я разбираю на практике задачи по проектированию систем.

Context — код для https://www.structurizr.com/dsl
 workspace {  model {     user = person "Клиент" "Использует приложение GetDelivery."     admin = person "Администратор" "Управляет приложением GetDelivery."      GetDelivery = softwareSystem "GetDelivery" "Сервис доставки." {         webApp = container "Web-приложение" "Интерфейс для клиентов." "Web Application"         mobileAppiOS = container "Mobile App iOS" "iOS приложение для клиентов." "iOS"         mobileAppAndroid = container "Mobile App Android" "Android приложение для клиентов." "Android"         adminWebApp = container "Web App Admin" "Интерфейс для администраторов." "Web Application"         backend = container "Backend" "Обрабатывает бизнес-логику." "Server-side Application"         database = container "База данных" "Хранит информацию о заказах, пользователях и т.д." "Database"         userDatabase = container "База данных пользователей" "Хранит данные пользователей." "Database"         reportStorage = container "Файловое хранилище отчетов" "Хранит PDF отчеты." "File Storage"         logicService = container "Сервис основной логики" "Обрабатывает основные функции системы." "Server-side Application"         deliveryIntegrationService = container "Сервис интеграций с сервисами доставки" "Интеграция с СДЭК, Возовоз, Деловые Линии." "Server-side Application"         authService = container "Сервис авторизации и регистрации пользователей" "Управляет авторизацией и регистрацией." "Server-side Application"         reportService = container "Сервис генерации отчетов" "Генерирует PDF отчеты." "Server-side Application"     }      cdek = softwareSystem "СДЭК" "Система доставки."     vozovoz = softwareSystem "Возовоз" "Система доставки."     delovieLinii = softwareSystem "Деловые Линии" "Система доставки."      user -> webApp "Использует"     user -> mobileAppiOS "Использует"     user -> mobileAppAndroid "Использует"     admin -> adminWebApp "Использует"     webApp -> backend "Взаимодействует"     mobileAppiOS -> backend "Взаимодействует"     mobileAppAndroid -> backend "Взаимодействует"     adminWebApp -> backend "Взаимодействует"     backend -> database "Использует"     backend -> userDatabase "Использует"     backend -> logicService "Использует"     backend -> deliveryIntegrationService "Использует"     backend -> authService "Использует"     backend -> reportService "Использует"     logicService -> reportStorage "Сохраняет отчеты"     reportService -> reportStorage "Сохраняет отчеты"     deliveryIntegrationService -> cdek "Интеграция"     deliveryIntegrationService -> vozovoz "Интеграция"     deliveryIntegrationService -> delovieLinii "Интеграция" }  views {     systemContext GetDelivery {         include *         autolayout lr     }      theme default } }

Пример проекта сервис-агрегатор для расчета наиболее выгодной стоимости доставки GetDelivery.

? Container

Описывает верхнеуровневую архитектуру и технологии. Используется для понимания технологического стека и разделения зон ответственности.

Элементы:
— контейнеры (например, веб-приложения, базы данных),
— взаимосвязи,
— технологии.

Пример проекта: Сервис-агрегатор GetDelivery из моего канала для системных аналитиков, где я разбираю на практике задачи по проектированию систем.

Container — код для https://www.structurizr.com/dsl
workspace {      model {         user = person "Клиент" "Использует приложение GetDelivery."         admin = person "Администратор" "Управляет приложением GetDelivery."          GetDelivery = softwareSystem "GetDelivery" "Сервис доставки." {             webApp = container "Web-приложение" "Интерфейс для клиентов." "Web Application"             mobileAppiOS = container "Mobile App iOS" "iOS приложение для клиентов." "iOS"             mobileAppAndroid = container "Mobile App Android" "Android приложение для клиентов." "Android"             adminWebApp = container "Web App Admin" "Интерфейс для администраторов." "Web Application"             backend = container "Backend" "Обрабатывает бизнес-логику, содержит сервисы и базы данных." "Server-side Application"         }          cdek = softwareSystem "СДЭК" "Система доставки."          vozovoz = softwareSystem "Возовоз" "Система доставки."         delovieLinii = softwareSystem "Деловые Линии" "Система доставки."          user -> webApp "Использует"         user -> mobileAppiOS "Использует"         user -> mobileAppAndroid "Использует"         admin -> adminWebApp "Использует"         webApp -> backend "API"         mobileAppiOS -> backend "API"         mobileAppAndroid -> backend "API"         adminWebApp -> backend "API"         backend -> cdek "HTTPS/JSON"         backend -> vozovoz "HTTPS/JSON"         backend -> delovieLinii "HTTPS/JSON"     }      views {         container GetDelivery {             include *             autolayout lr         }          theme default     } } 

? Component

Детализирует структуру внутри контейнера системы, т.е. описывает более детально только один контейнер из предыдущего уровня.

Используется для проектирования и документирования внутренней структуры компонентов системы.

Элементы:
— компоненты,
— взаимосвязи,
— технологии,
— зависимости.

Пример проекта: Сервис-агрегатор GetDelivery из моего канала для системных аналитиков, где я разбираю на практике задачи по проектированию систем.

Реализована в Draw.io

Реализована в Draw.io

Про возможности Structurizr

Дополнительно для этой диаграммы хочу взять пример из официальной документации, чтобы вы увидели, как многослойно и красиво всё может быть сделано кодом в рамках одной схемы.

Пример кода диаграммы Component и других уровней
/*  * This is a combined version of the following workspaces, with automatic layout enabled:  *  * - "Big Bank plc - System Landscape" (https://structurizr.com/share/28201/)  * - "Big Bank plc - Internet Banking System" (https://structurizr.com/share/36141/) */ workspace "Big Bank plc" "This is an example workspace to illustrate the key features of Structurizr, via the DSL, based around a fictional online banking system." {      model {         customer = person "Personal Banking Customer" "A customer of the bank, with personal bank accounts." "Customer"          group "Big Bank plc" {             supportStaff = person "Customer Service Staff" "Customer service staff within the bank." "Bank Staff"             backoffice = person "Back Office Staff" "Administration and support staff within the bank." "Bank Staff"              mainframe = softwaresystem "Mainframe Banking System" "Stores all of the core banking information about customers, accounts, transactions, etc." "Existing System"             email = softwaresystem "E-mail System" "The internal Microsoft Exchange e-mail system." "Existing System"             atm = softwaresystem "ATM" "Allows customers to withdraw cash." "Existing System"              internetBankingSystem = softwaresystem "Internet Banking System" "Allows customers to view information about their bank accounts, and make payments." {                 singlePageApplication = container "Single-Page Application" "Provides all of the Internet banking functionality to customers via their web browser." "JavaScript and Angular" "Web Browser"                 mobileApp = container "Mobile App" "Provides a limited subset of the Internet banking functionality to customers via their mobile device." "Xamarin" "Mobile App"                 webApplication = container "Web Application" "Delivers the static content and the Internet banking single page application." "Java and Spring MVC"                 apiApplication = container "API Application" "Provides Internet banking functionality via a JSON/HTTPS API." "Java and Spring MVC" {                     signinController = component "Sign In Controller" "Allows users to sign in to the Internet Banking System." "Spring MVC Rest Controller"                     accountsSummaryController = component "Accounts Summary Controller" "Provides customers with a summary of their bank accounts." "Spring MVC Rest Controller"                     resetPasswordController = component "Reset Password Controller" "Allows users to reset their passwords with a single use URL." "Spring MVC Rest Controller"                     securityComponent = component "Security Component" "Provides functionality related to signing in, changing passwords, etc." "Spring Bean"                     mainframeBankingSystemFacade = component "Mainframe Banking System Facade" "A facade onto the mainframe banking system." "Spring Bean"                     emailComponent = component "E-mail Component" "Sends e-mails to users." "Spring Bean"                 }                 database = container "Database" "Stores user registration information, hashed authentication credentials, access logs, etc." "Oracle Database Schema" "Database"             }         }          # relationships between people and software systems         customer -> internetBankingSystem "Views account balances, and makes payments using"         internetBankingSystem -> mainframe "Gets account information from, and makes payments using"         internetBankingSystem -> email "Sends e-mail using"         email -> customer "Sends e-mails to"         customer -> supportStaff "Asks questions to" "Telephone"         supportStaff -> mainframe "Uses"         customer -> atm "Withdraws cash using"         atm -> mainframe "Uses"         backoffice -> mainframe "Uses"          # relationships to/from containers         customer -> webApplication "Visits bigbank.com/ib using" "HTTPS"         customer -> singlePageApplication "Views account balances, and makes payments using"         customer -> mobileApp "Views account balances, and makes payments using"         webApplication -> singlePageApplication "Delivers to the customer's web browser"          # relationships to/from components         singlePageApplication -> signinController "Makes API calls to" "JSON/HTTPS"         singlePageApplication -> accountsSummaryController "Makes API calls to" "JSON/HTTPS"         singlePageApplication -> resetPasswordController "Makes API calls to" "JSON/HTTPS"         mobileApp -> signinController "Makes API calls to" "JSON/HTTPS"         mobileApp -> accountsSummaryController "Makes API calls to" "JSON/HTTPS"         mobileApp -> resetPasswordController "Makes API calls to" "JSON/HTTPS"         signinController -> securityComponent "Uses"         accountsSummaryController -> mainframeBankingSystemFacade "Uses"         resetPasswordController -> securityComponent "Uses"         resetPasswordController -> emailComponent "Uses"         securityComponent -> database "Reads from and writes to" "SQL/TCP"         mainframeBankingSystemFacade -> mainframe "Makes API calls to" "XML/HTTPS"         emailComponent -> email "Sends e-mail using"          deploymentEnvironment "Development" {             deploymentNode "Developer Laptop" "" "Microsoft Windows 10 or Apple macOS" {                 deploymentNode "Web Browser" "" "Chrome, Firefox, Safari, or Edge" {                     developerSinglePageApplicationInstance = containerInstance singlePageApplication                 }                 deploymentNode "Docker Container - Web Server" "" "Docker" {                     deploymentNode "Apache Tomcat" "" "Apache Tomcat 8.x" {                         developerWebApplicationInstance = containerInstance webApplication                         developerApiApplicationInstance = containerInstance apiApplication                     }                 }                 deploymentNode "Docker Container - Database Server" "" "Docker" {                     deploymentNode "Database Server" "" "Oracle 12c" {                         developerDatabaseInstance = containerInstance database                     }                 }             }             deploymentNode "Big Bank plc" "" "Big Bank plc data center" "" {                 deploymentNode "bigbank-dev001" "" "" "" {                     softwareSystemInstance mainframe                 }             }          }          deploymentEnvironment "Live" {             deploymentNode "Customer's mobile device" "" "Apple iOS or Android" {                 liveMobileAppInstance = containerInstance mobileApp             }             deploymentNode "Customer's computer" "" "Microsoft Windows or Apple macOS" {                 deploymentNode "Web Browser" "" "Chrome, Firefox, Safari, or Edge" {                     liveSinglePageApplicationInstance = containerInstance singlePageApplication                 }             }              deploymentNode "Big Bank plc" "" "Big Bank plc data center" {                 deploymentNode "bigbank-web***" "" "Ubuntu 16.04 LTS" "" 4 {                     deploymentNode "Apache Tomcat" "" "Apache Tomcat 8.x" {                         liveWebApplicationInstance = containerInstance webApplication                     }                 }                 deploymentNode "bigbank-api***" "" "Ubuntu 16.04 LTS" "" 8 {                     deploymentNode "Apache Tomcat" "" "Apache Tomcat 8.x" {                         liveApiApplicationInstance = containerInstance apiApplication                     }                 }                  deploymentNode "bigbank-db01" "" "Ubuntu 16.04 LTS" {                     primaryDatabaseServer = deploymentNode "Oracle - Primary" "" "Oracle 12c" {                         livePrimaryDatabaseInstance = containerInstance database                     }                 }                 deploymentNode "bigbank-db02" "" "Ubuntu 16.04 LTS" "Failover" {                     secondaryDatabaseServer = deploymentNode "Oracle - Secondary" "" "Oracle 12c" "Failover" {                         liveSecondaryDatabaseInstance = containerInstance database "Failover"                     }                 }                 deploymentNode "bigbank-prod001" "" "" "" {                     softwareSystemInstance mainframe                 }             }              primaryDatabaseServer -> secondaryDatabaseServer "Replicates data to"         }     }      views {         systemlandscape "SystemLandscape" {             include *             autoLayout         }          systemcontext internetBankingSystem "SystemContext" {             include *             animation {                 internetBankingSystem                 customer                 mainframe                 email             }             autoLayout             description "The system context diagram for the Internet Banking System."             properties {                 structurizr.groups false             }         }          container internetBankingSystem "Containers" {             include *             animation {                 customer mainframe email                 webApplication                 singlePageApplication                 mobileApp                 apiApplication                 database             }             autoLayout             description "The container diagram for the Internet Banking System."         }          component apiApplication "Components" {             include *             animation {                 singlePageApplication mobileApp database email mainframe                 signinController securityComponent                 accountsSummaryController mainframeBankingSystemFacade                 resetPasswordController emailComponent             }             autoLayout             description "The component diagram for the API Application."         }          image mainframeBankingSystemFacade "MainframeBankingSystemFacade" {             image https://raw.githubusercontent.com/structurizr/examples/main/dsl/big-bank-plc/internet-banking-system/mainframe-banking-system-facade.png             title "[Code] Mainframe Banking System Facade"         }          dynamic apiApplication "SignIn" "Summarises how the sign in feature works in the single-page application." {             singlePageApplication -> signinController "Submits credentials to"             signinController -> securityComponent "Validates credentials using"             securityComponent -> database "select * from users where username = ?"             database -> securityComponent "Returns user data to"             securityComponent -> signinController "Returns true if the hashed password matches"             signinController -> singlePageApplication "Sends back an authentication token to"             autoLayout             description "Summarises how the sign in feature works in the single-page application."         }          deployment internetBankingSystem "Development" "DevelopmentDeployment" {             include *             animation {                 developerSinglePageApplicationInstance                 developerWebApplicationInstance developerApiApplicationInstance                 developerDatabaseInstance             }             autoLayout             description "An example development deployment scenario for the Internet Banking System."         }          deployment internetBankingSystem "Live" "LiveDeployment" {             include *             animation {                 liveSinglePageApplicationInstance                 liveMobileAppInstance                 liveWebApplicationInstance liveApiApplicationInstance                 livePrimaryDatabaseInstance                 liveSecondaryDatabaseInstance             }             autoLayout             description "An example live deployment scenario for the Internet Banking System."         }          styles {             element "Person" {                 color #ffffff                 fontSize 22                 shape Person             }             element "Customer" {                 background #08427b             }             element "Bank Staff" {                 background #999999             }             element "Software System" {                 background #1168bd                 color #ffffff             }             element "Existing System" {                 background #999999                 color #ffffff             }             element "Container" {                 background #438dd5                 color #ffffff             }             element "Web Browser" {                 shape WebBrowser             }             element "Mobile App" {                 shape MobileDeviceLandscape             }             element "Database" {                 shape Cylinder             }             element "Component" {                 background #85bbf0                 color #000000             }             element "Failover" {                 opacity 25             }         }     } }

Источник: https://github.com/structurizr/examples/tree/main/dsl (big-bank-pic)

Если скопируете код и вставите в https://www.structurizr.com/dsl, то увидете следующее:

Дополнительный пример уровня Component из Miro для проекта Зоомагазина:

? Code

Показывает детали реализации отдельных компонентов.

Используется для документирования структуры кода. На практике не используется, т.к. разработчикам это не надо. Это как диаграмма классов UML: вроде полезно понимать, а по факту не нужна.

Элементы:
— классы,
— интерфейсы,
— отношения между ними.

Пример можно посмотреть на сайте автора нотации — Саймона Брауна по банковскому проекту.

Где создавать схемы C4 — инструменты

Для создания схем в нотации C4 можно использовать:

  • графические инструменты,

  • инструменты визуализации через код (+ ChatGPT).

Использование инструментов, которые позволяют описывать C4 через код, позволяют ускорить процесс за счет использования искусственного интеллекта — ChatGPT или аналог.

1. Draw.io — графический инструмент

Draw.io (diagrams.net) — это бесплатный онлайн-инструмент, который подходит для создания различных видов диаграмм, включая C4. Он предоставляет широкий набор элементов дизайна, что делает его удобным для быстрого создания диаграмм.

Есть минусы в редактировании, когда на диаграмме много элементов: бывает, что перемещаешь не то что хотел, или не так, как хотел.

Плюсы:
+ Бесплатный;
+ Есть все виды диаграмм;
+ Есть интеграция с Confluence, Google Drive и другими постоянно используемыми программами.

Минусы:
— Большие схемы приводят к страданиями при редактировании. Это проблема всех графических редакторов.

Заключение:
Если у меня стоит задача отрисовать схему архитектуры в нотации C4 через графический инструмент, то я буду это делать в Draw.io. В GetAnalyst используем этот инструмент как основной.

Как включить C4 в Draw.io
Добавление элементов С4 в Draw.io

Добавление элементов С4 в Draw.io
Пример C4 в Draw.io

Пример C4 в Draw.io

2. Miro — графический инструмент

Miro — это онлайн-платформа для визуального создания и обсуждения проектов на электронных досках, которая также может быть использована для создания C4 диаграмм.

Для использования Miro в качестве средства визуализации схемы архитектуры, я рекомендую вам взять мой шаблон Miro с элементами C4 и копировать элементы из него.

Плюсы:
+ Есть интеграция с Confluence, Google Drive и другими постоянно используемыми программами.
+ Приятный и удобный интерфейс, более современно выглядит, чем Draw.io.

Минусы:
— Ограничение на количество бесплатных досок, поэтому условно платный.
— Большие схемы приводят к страданиями при редактировании.
— Элементы C4 не стандартные для Miro, что может приводить к проблемам при редактировании.

Заключение:
При сравнении опыта работы с Miro и Draw.io, я остаюсь сторонником более простого и удобного Draw.io, так как для Miro возможность отрисовки C4 скорее неожиданная опция, чем удобная фича.

Шаблон Miro с элементами C4

Шаблон Miro с элементами C4

3. Microsoft Visio — графический инструмент

Microsoft Visio от Microsoft — это профессиональное решение для создания сложных диаграмм. Аналогичен по функциональности Draw.io, и скорее всего шаблоны элементов C4 придётся сначала создать, как в Miro.

Плюсы:
+ Распространен в IT-компаниях.

Минусы:
— Платный.
— Работа в оффлайн, хотя для кого-то это может быть и плюсом.
— Не предназначен для C4.

Заключение:
Я выберу draw.io, так как несколько лет не открывала Visio и у меня уже больше года не Windows.

4. Structurizr — инструмент визуализации через код

Structurizr — это один из самых специализированных инструментов для создания диаграмм C4. Structurizr позволяет определять их через код, что обеспечивает высокую гибкость и точность в описании архитектуры.

Чтобы использовать Structurizr для описания архитектуры в нотации C4:

  1. Используйте онлайн-интерфейс с редактором DSL: https://www.structurizr.com/dsl.

  2. Напишите или вставьте приведенный ниже код в редактор Structurizr.

  3. Нажмите «Render» справа сверху, над панелью с кодом, чтобы увидеть вашу диаграмму.

Плюсы:
+ Бесплатный.
+ Удобный в использовании.
+ Понятный язык разметки, которым «рисовать».
+ Поддерживает генерацию кода через искусственный интеллект (ChatGPT).
+ Визуально простой и понятный.
+ Чистый интерфейс — нет мусорной рекламы.
+ Можно даже писать на Java код для визуализации.
+ Потрясающая база знаний с примерами на английском языке.

Минусы:
— Могут быть сложности с визуализацией больших диаграмм.

Заключение:
Брать и использовать.

Примеры кода для Structurizr — Context

Код для диаграммы на уровне Context:

workspace {      model {         user = person "Пользователь" "Описание пользователя."         bankingSystem = softwareSystem "Банковская Система" "Описание банковской системы."          user -> bankingSystem "Использует" "HTTPS"     }      views {         systemContext bankingSystem {             include *             autoLayout lr         }          theme default     } } 

Этот код создает диаграмму контекста с двумя элементами:

  1. «Пользователь» (отображается как Person в PlantUML), который взаимодействует с системой.

  2. «Банковская Система» (отображается как System), которая представляет собой внешнюю систему, с которой взаимодействует пользователь.

Между этими элементами устанавливается связь с описанием «Использует» и протоколом «HTTPS».

Примеры кода для Structurizr — Container

Код для уровня Container:

workspace {      model {         user = person "Пользователь" "Описание пользователя."          bankingSystem = softwareSystem "Банковская Система" {             webApp = container "Веб-приложение" "Предоставляет банковские услуги онлайн." "Java"             db = container "База Данных" "Хранит данные о счетах и транзакциях." "MySQL"             api = container "API" "Предоставляет API для доступа к данным." "RESTful"         }          user -> webApp "Использует" "HTTPS"         webApp -> db "Читает/записывает" "JDBC"         api -> db "Запрашивает" "JDBC"     }      views {         container bankingSystem {             include *             autoLayout lr         }          theme default     } } 

Этот код создаёт диаграмму контейнеров внутри системы «Банковская Система». Здесь мы видим:

  1. Пользователь, который взаимодействует с веб-приложением.

  2. В Банковской Системе теперь определены три контейнера:

    • Веб-приложение: Представляет собой пользовательский интерфейс, написанный на Java.

    • База Данных: MySQL база данных, хранящая информацию.

    • API: RESTful API для доступа к данным базы.

Примеры кода для Structurizr — Component

Детализирует контейнер «Веб-приложение» из предыдущего примера.

В этом примере мы фокусируемся на компонентах внутри «Веб-приложения»:

Также показаны связи между этими компонентами, а также их взаимодействие с внешними контейнерами, такими как «API» и физическая «База Данных».

Код для уровня Component:

workspace {      model {         user = person "Пользователь" "Описание пользователя."                           bankingSystem = softwareSystem "Банковская Система" {         webApp = container "Веб-приложение" {             ui = component "Пользовательский Интерфейс" "Angular, Предоставляет веб-интерфейс для пользователей."             server = component "Серверная Логика" "Spring Boot, Обрабатывает запросы от пользовательского интерфейса."             databaseComponent = component "Компонент Базы Данных" "JPA/Hibernate, Обеспечивает доступ к данным."         }          api = container "API" "RESTful, Предоставляет API для доступа к данным."         db = container "База Данных" "MySQL, Хранит данные о счетах и транзакциях."          user -> ui "Использует" "HTTPS"         ui -> server "Вызывает" "JSON/HTTP"         server -> databaseComponent "Использует" "JDBC"         server -> api "Делает запросы" "JSON/HTTP"         databaseComponent -> db "Читает/Записывает" "JDBC"         }     }      views {         component webApp {             include *             autoLayout lr         }          theme default     } } 

5. PlantUML — инструмент визуализации через код

PlantUML — это инструмент, который позволяет создавать UML-диаграммы из текстового описания. Он поддерживает синтаксис для создания диаграмм C4, но работает с перебоями — периодически не поддерживает загрузку визуализатора по ссылке и выдаёт ошибку. Поэтому рекомендую использовать только от большой любви к PlantUML.

Плюсы:
+ Можно аккуратно визуализировать диаграммы через код.

Минусы:
— Работает нестабильно.

Заключение:
Structurizr лучше подходит для создания C4-диаграмм через код.

Чтобы использовать PlantUML для описания архитектуры в нотации C4:

  1. Используйте онлайн-интерфейс PlantUML, такой как PlantText или онлайн-редактор PlantUML на сайте plantuml.com.

  2. Напишите или вставьте приведенный ниже код в редактор PlantUML.

  3. Диаграмма будет автоматически сгенерирована на основе этого текстового описания. Либо нажмите «Submit».

*В случае проблем с отображением из-за недоступности URL https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Context.puml внутри PlantUML смените браузер или переключитесь несколько раз между дневным и ночным режимами (переключатель справа от кнопки «Submit»).

Примеры кода для PlantUML

Context

Пример кода на PlantUML для диаграммы на уровне Context:

@startuml C4_Example !include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Context.puml  LAYOUT_WITH_LEGEND()  Person(user, "Пользователь", "Описание пользователя.") System(bankingSystem, "Банковская Система", "Описание банковской системы.")  Rel(user, bankingSystem, "Использует", "HTTPS") @enduml

*Если не увидете диаграмму сразу, переключитесь в темную/светлую тему или смените браузер. Бывают проблемы с установкой соединения.

Куча рекламы вокруг печалит.

Куча рекламы вокруг печалит.

Container

Код для уровня Container:

@startuml C4_Containers !include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml  LAYOUT_WITH_LEGEND()  Person(user, "Пользователь", "Описание пользователя.")  System_Boundary(bankingSys, "Банковская Система") {     Container(webApp, "Веб-приложение", "Java", "Предоставляет банковские услуги онлайн.")     Container(db, "База Данных", "MySQL", "Хранит данные о счетах и транзакциях.")     Container(api, "API", "RESTful", "Предоставляет API для доступа к данным.") }  Rel(user, webApp, "Использует", "HTTPS") Rel(webApp, db, "Читает/записывает", "JDBC") Rel(api, db, "Запрашивает", "JDBC") @enduml

Component

Детализируем «Веб-приложение» из предыдущего примера. Код для уровня Component:

@startuml !include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Component.puml  LAYOUT_WITH_LEGEND()  Container_Boundary(webApp, "Веб-приложение") {     Component(ui, "Пользовательский Интерфейс", "Angular", "Предоставляет веб-интерфейс для пользователей.")     Component(server, "Серверная Логика", "Spring Boot", "Обрабатывает запросы от пользовательского интерфейса.")     Component(database, "База Данных", "JPA/Hibernate", "Обеспечивает доступ к данным.") }  Container(api, "API", "RESTful", "Предоставляет API для доступа к данным.") Container(db, "База Данных", "MySQL", "Хранит данные о счетах и транзакциях.")  Person(user, "Пользователь", "Описание пользователя.") Rel(user, ui, "Использует", "HTTPS")  Rel(ui, server, "Вызывает", "JSON/HTTP") Rel(server, database, "Использует", "JDBC") Rel(server, api, "Делает запросы", "JSON/HTTP") Rel(database, db, "Читает/Записывает", "JDBC") @enduml

Выводы

Выбор инструмента зависит от личных предпочтений, требований проекта и уровня комфорта в работе с конкретными инструментами. Некоторые предпочитают инструменты с графическим интерфейсом для более интуитивного процесса, в то время как другие могут выбрать кодовые инструменты для большей автоматизации и точности.

Я рекомендую для создания диаграммы C4 инструменты Draw.io и Structurizr.

Заключение

Я считаю C4 наиболее понятной и доступной нотацией моделирования архитектуры, которая помогает команде разработки. Диаграммы легко читаются всеми участниками за счет того, что содержат ограниченный набор обозначений.

Сама в практике, как системный аналитик, я также часто использую упрощенные модели, базирующиеся на C4, когда нужно показать что-то большое. На больших схемах прямоугольники C4 занимают много пространства и становится затруднительно знакомиться со схемой на маленьком мониторе, да и на большом тоже.

Наиболее полезные уровни:

  • Context — общее представление, полезен для понимания внешних взаимодействий с системой — интеграций.

  • Container — устройство системы внутри, подходит для понимания какие есть веб-, мобильные, серверные, и другие виды приложений.

  • Component — идеально подходит для документирования архитектуры Backend, основной уровень описания архитектуры, который требует внимания на проекте.

Уровень кода Code считаю ненужной тратой времени. В роли системного аналитика проектирования структуры кода я не касаюсь, а документирование кода разработчиками в C4 или в диаграмме классов UML скорее вызовет у меня ощущение бюрократического шока, чем восхищение. Лучше комментарии нормальные оставить.

Дополнительно примеры схем архитектуры в можно посмотреть в моем канале в этом посте, и сверху-снизу от него.

Если вы хотите ввести стандарт документирования архитектуры в своей компании, то нотация C4 идеальна, чтобы начать с неё (а затем адаптировать под что-то своё, при необходимости).

Нотация C4 — мощный инструмент, обеспечивающий ясность и структурированность в процессе проектирования архитектуры систем. Эта нотация не только помогает архитекторам и разработчикам в создании целостного представления системы, но и способствует улучшению коммуникаций разработчиков и архитекторов с менеджерами проектов, аналитиками и другими заинтересованными сторонами.

Дополнительная информация

Теория и примеры

  1. The C4 model for visualising software architecture
    The C4 model and this website were created by Simon Brown
    Первоисточник с теорией по нотации, где можно искать ответы на вопросы «как правильно…».

  2. Примеры архитектуры для интеграционных проектов:

    1. Зоо-магазин онлайн.

    2. Логистический сервис: от монолита до микросервисов.

  3. Еще одна хорошая статья на Habr с аккуратным примером и теорией.
    Как описать большую систему в нотации С4.

Инструменты

  1. Пример схемы архитектуры проекта в Miro — интернет-зоомагазин
    Екатерина Ананьева
    Пример схемы архитектуры в нотации С4, на основе которого можно изучать нотацию и из которого можно переносить шаблоны элементов в свой собственный Miro.

  2. C4 Model with PlantUML (англ)
    Huseyin Kutluca
    Статья про возможность использования PlantUML для создания диаграмм в нотации C4. В ней можно взять дополнительные примеры для изучения и лучше понять подход к написанию кода.

  3. https://github.com/structurizr/examples/tree/main/dsl
    База данных с примерами для инструмента structurizr, с помощью которого можно описывать диаграммы C4 через код.


ссылка на оригинал статьи https://habr.com/ru/articles/778726/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *