Слово "компонент" — одно из самых перегруженных в разработке. В Unity это MonoBehaviour, в ECS — struct с данными, в пакетном менеджере — package.
В модели C4 — совершенно другое.
Много раз видел как разработчики рисуют схемы, добавляя на одну диаграмму и крупные подсистемы (UI, Networking, Analytics), и конкретные классы внутри них.
Всё на одном листе, без разделения по масштабу.
Результат — схема, которую понимает только автор.
И вот в чём причина. Между уровнем контейнеров ("что мы деплоим") и уровнем кода ("какие классы пишем") — пропасть.
Контейнеры слишком крупные чтобы по ним начинать имплементацию. Классы слишком мелкие чтобы по ним планировать.
Без промежуточного уровня разработчик вынужден мешать оба на одной схеме. Отсюда каша.
🔸Что такое компонент в C4
Компонент в модели C4 — это группа связанной функциональности за чётким интерфейсом (API, модель, фасад). Не один класс, не файл — а логическая единица (чаще папка), выделенная из кода по ответственности.
Компонент:
▫️ Живёт внутри контейнера
▫️ НЕ деплоится отдельно — деплоится контейнер
▫️ Все компоненты одного контейнера выполняются в одном процессе
В Unity-проекте ближайшая аналогия — внутренняя структура asmdef: из каких подсистем она состоит.
Но маппинг не 1:1 — один компонент может быть размазан по нескольким asmdef, а одна asmdef может содержать несколько компонентов.
❗️ Уровень компонентов и Unity-компоненты (MonoBehaviour/IComponentData) — абсолютно разные, не связанные понятия.
🔸Пример: Unity-клиент
В статье про контейнеры мы установили — Unity-клиент это монолит, 1 деплоемый unit. Но внутри этого монолита есть структура.
В типичном проекте есть инфраструктурный слой, который очевиден:
— UI, Networking, Assets, Analytics, Save
Но ценность уровня компонентов проявляется в декомпозиции игровой логики. Именно тут начинаются вопросы:
▫️ Battle System — боевая механика, расчёт урона, управление раундами
▫️ Meta Game — прогрессия, апгрейды, разблокировки
▫️ Social — кланы, чат, друзья, лидерборды
▫️ Economy — валюты, магазин, инвентарь, покупки
Каждый — группа систем и их фасадов (моделей), которые предоставляют API внешним системам.
На уровне компонентов нам не важно что внутри. Важно что он делает и с чем связан.
🔸Когда это нужно, а когда нет
Сайт C4 прямо говорит:
component diagram — not recommended by default.
Делай только если приносит пользу.
Когда я проектировал чат в Nexters, лид инфраструктурного направления требовал проектирования уровня контейнеров — какие сервисы, как деплоятся, как связаны. Но когда я запроектировал и уровень компонентов, он сказал: "это излишне".
Для него — да. Но когда дело дошло до имплементации, именно запроектированный уровень компонентов помог мне и команде разбить работу на независимые части, отдельно описать по ним требования и распараллелить задачи.
🔹 Уровень контейнеров — для инфраструктурщиков: как сервис встраивается в инфраструктуру
🔹 Уровень компонентов — для программистов: как разбить систему на части и распределить работу
🔸Как не свалиться в код
Если на схеме появляются конкретные классы — ты уже на уровне кода.
Компонент описывается через ответственность, а не реализацию:
— ✅ "Economy — управление валютами, покупками и инвентарём"
— ❌ "WalletService вызывает TransactionValidator, который использует CurrencyConverter"
Смешивая уровни, ты получаешь схему, которую понимаешь только ты, + ускоряешь устаревание документации.
Уровень кода меняется гораздо чаще, чем уровень компонентов.
🔻 Уровень компонентов существует чтобы закрыть разрыв между "что мы деплоим" и "какие классы пишем".
Без него — либо проектируешь слишком крупно и схема бесполезна для имплементации, либо слишком мелко и схема нечитаема.
Следующая статья серии — уровень кода. Тот самый, который стоит генерировать, а не проектировать ручками 😅
Ставь 👍 если тебе заходит такого рода контент!
Ты знаешь кому переслать эту статью 💪
#проектирование@UniArchitect
