Files
slm-design/docs/architecture/README.md
2026-08-10 12:37:32 +03:00

9.6 KiB
Raw Blame History

Архитектура SLM

SLM описывает владение ответственностями внутри одного фронтенд-приложения. Слой определяет роль кода, группа классифицирует модули, модуль владеет ответственностью, а сегмент организует реализацию владельца.

Владение как основа

Ответственность — результат или поведение приложения, за которое отвечает один модуль-владелец. Она становится самостоятельной, когда ей нужны собственный публичный контракт, зависимости, состояние или область жизни, а не только внутренняя роль в работе другого модуля. Props, импорты, локальное состояние и lifecycle-код сами по себе этого не доказывают.

У каждой самостоятельной ответственности есть ровно один владелец. В SLM владельцем является модуль. Он определяет:

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

Каждый файл принадлежит ближайшей модульной границе и реализует ответственность этого модуля. Место выполнения или вид кода не меняют владельца.

Структурная модель

SLM root
└── слой
    ├── модуль
    │   ├── сегмент
    │   └── вложенный модуль
    │       ├── сегмент
    │       └── вложенный модуль
    └── группа
        ├── модуль
        └── группа
            └── модуль
Сущность Назначение Владеет ответственностью
Слой Классифицирует код по архитектурной роли Нет
Группа Навигационно классифицирует модули внутри слоя Нет
Модуль Владеет одной самостоятельной ответственностью Да
Сегмент Организует внутренности одного модуля Нет

Вложенный модуль является обычным модулем, размещённым внутри родительского. Он владеет отдельно сформулированной подответственностью и создаёт следующий рекурсивный структурный уровень.

Слой и группа находятся снаружи модульной границы. Сегмент находится внутри неё. Framework-компоненты, Providers, Guards, hooks, stores, services и другой внутренний код не являются архитектурными сущностями SLM и принадлежат ближайшему модулю.

Внутренняя реализация

Модуль может содержать любой код, относящийся к его ответственности. SLM ограничивает не набор framework-механизмов, а владение и наблюдаемую структуру:

  • помимо опционального главного framework-файла в корне, остальные компонентные единицы располагаются на одном внутреннем уровне относительно модуля;
  • каталог компонентной единицы не содержит другие компонентные единицы или вложенные модули;
  • рекурсивная структурная вложенность создаётся только вложенными модулями;
  • помимо публичных фасетов, в корне находится не более одного главного implementation- или assembly-файла;
  • если главный файл нельзя определить уверенно, реализация размещается в сегментах.

Ограничение глубины framework-компонентов относится к файловой организации, а не к runtime-дереву фреймворка.

Порядок проектирования

Архитектурное решение принимается от смысла к структуре:

  1. Описать результат, который должен получить пользователь или приложение.
  2. Назначить модуль, который отвечает за этот результат.
  3. Определить, что модуль делает сам, а что получает от других модулей.
  4. Определить, кто использует результат работы модуля.
  5. Выбрать слой по роли ответственности.
  6. Спроектировать публичный API и допустимые зависимости.
  7. При необходимости классифицировать модули группами, организовать внутренний код сегментами и выбрать физические пути.

Например, Header сам определяет расположение шапки, отображение навигации и состояние мобильного меню. Текущего пользователя он получает от модуля auth, а Button и Avatar — от модулей ui. Если удалить Header, авторизация и UI-компоненты останутся нужны приложению, поэтому Header использует их, но не владеет ими.

Если ответственность или владелец не определены, файловая структура не может исправить архитектурную неопределённость.

Логическая и физическая границы

Модуль не определяется наличием папки, index.ts, framework-компонента или нескольких файлов. Его определяет самостоятельная ответственность и владение её контрактом, зависимостями, состоянием и жизненным циклом.

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

Верны обе формулировки:

  • самостоятельная ответственность требует модульной границы;
  • отдельная папка сама по себе не доказывает наличие модуля.

Пути сопоставляются со слоями, группами, модулями, вложенными модулями и сегментами в стайлгайде или конфигурации конкретного проекта. Имя пути не меняет нормативный смысл сущности.

Область применения

SLM применяется внутри SLM root — границы структурной архитектуры одного приложения. Это может быть src/ или другая область, установленная проектом.

Архитектура определяет:

  • роли слоёв и допустимые межслойные направления;
  • владельцев самостоятельных ответственностей;
  • публичные границы модулей;
  • общий ацикличный граф модулей;
  • назначение групп и сегментов;
  • внутреннюю глубину framework-компонентных единиц;
  • владение состоянием и жизненным циклом ресурсов.

SLM не задаёт обязательный поток данных, конкретный framework, фиксированные имена сегментов, правила монорепозиториев или полный файловый стайлгайд.

Нормативный смысл терминов находится в терминологии. Точные блокирующие требования объявлены только в реестре правил.