7.2 KiB
Слои SLM
Пояснение нормативной модели слоёв SLM.
Базовая структура
src/
├── app/
├── compositions/
├── domains/
├── infra/
├── ui/
└── shared/
src/ здесь является примером SLM root. Фактическую границу определяет устройство приложения.
Отсутствующая в проекте роль не требует пустой папки. Слой является доступной архитектурной ролью, а не обязательным элементом каркаса.
Роли слоёв
App
app связывает приложение с фреймворком: запускает его, объявляет маршруты, преобразует входные данные и подключает публичные API модулей разрешённых слоёв или ресурсы shared. Файлы app являются точками входа фреймворка, а не модулями SLM.
Точка входа может напрямую использовать compositions, domains, infra, ui или shared, если зависимость разрешена матрицей слоёв. Такое использование не переносит ответственность импортируемого модуля в app.
Compositions
compositions содержит продуктовый интерфейс: страницы, макеты, экраны, виджеты, точки входа и другие композиционные модули. Внутреннюю группировку слоя определяет проект.
Domains
domains содержит обычные SLM-модули, владеющие предметными ответственностями приложения: моделями, правилами, сценариями и продуктовым состоянием.
Предметная логика не принадлежит устройству одной страницы или маршрута. Конкретный visual outcome и сборка нескольких предметных ответственностей остаются в compositions.
Infra
infra содержит технические сервисы приложения: аналитику, локализацию, тему, телеметрию и другие возможности среды выполнения без самостоятельной предметной модели.
UI
ui содержит универсальные модули интерфейса, которые не зависят от конкретной страницы или продуктовой композиции.
Shared
shared содержит независимый детерминированный фундамент без знания о продукте, изменяемого состояния и ввода-вывода.
В shared допускаются обычные модули и специальные немодульные ресурсы: небольшие чистые утилиты, общие типы, стили, конфигурация и статические файлы. Ресурс не имеет самостоятельной ответственности, публичного API или жизненного цикла и может импортироваться напрямую по пути, установленному стайлгайдом.
Если ресурсу нужны самостоятельная ответственность, собственные архитектурные зависимости, несколько файлов реализации, изменяемое состояние, ввод-вывод или область жизни, он оформляется как модуль. Каталог ресурсов не реэкспортирует модули и не используется для обхода их публичных API.
Матрица зависимостей
app
|
compositions
|
domains
|
infra
|
ui
|
shared
Код слоя может импортировать модули своего слоя и слоёв, разрешённых строкой матрицы. Разрешённая зависимость может пропускать промежуточные роли.
| Слой | Может импортировать |
|---|---|
app |
app, compositions, domains, infra, ui, shared |
compositions |
compositions, domains, infra, ui, shared |
domains |
domains, infra, ui, shared |
infra |
infra, ui, shared |
ui |
ui, shared |
shared |
shared |
infra может импортировать ui, когда технической возможности требуется визуальное представление, например CAPTCHA, платёжный виджет, карта, uploader, уведомление или инструмент разработчика. Такое представление остаётся частью технической ответственности и не переносит в infra страницы, продуктовые тексты или композицию нескольких модулей.
ui не импортирует infra. Универсальный UI получает локализованный текст, тему, callbacks аналитики и другие технические возможности через входной контракт. Если UI-модулю необходимо напрямую знать конкретный технический сервис приложения, интеграция размещается в infra, domains или compositions, а универсальная часть остаётся в ui.
Импорты внутри слоя, публичный API и циклы описаны отдельно в Зависимостях.
Связанные правила
Граница слоя
Разрешённый импорт не переносит владение. Например, модуль слоя domains может использовать infra и ui, но технический сервис и универсальный интерфейс сохраняют собственных владельцев.
Если код определяет продуктовую модель, правило или сценарий, он принадлежит domains, а не shared или infra. Внутренняя форма домена определяется его ответственностью и реальными потребителями.