mirror of
https://github.com/gromlab-ru/slm-design.git
synced 2026-08-22 07:30:16 +03:00
chore: sync
This commit is contained in:
@@ -4,17 +4,17 @@ SLM описывает владение ответственностями вн
|
||||
|
||||
## Владение как основа
|
||||
|
||||
**Ответственность** — связная часть приложения с одной причиной изменяться. Она становится самостоятельной, когда ей нужны собственный публичный контракт, зависимости, состояние или область жизни.
|
||||
**Ответственность** — результат или поведение приложения, за которое отвечает один модуль-владелец. Она становится самостоятельной, когда ей нужны собственный публичный контракт, зависимости, состояние или область жизни, а не только внутренняя роль в работе другого модуля. Props, импорты, локальное состояние и lifecycle-код сами по себе этого не доказывают.
|
||||
|
||||
У каждой самостоятельной ответственности есть ровно один владелец. В SLM владельцем является модуль. Он определяет:
|
||||
|
||||
- какие возможности доступны внешним потребителям;
|
||||
- от каких других возможностей зависит ответственность;
|
||||
- от каких других модулей зависит ответственность;
|
||||
- кому принадлежат данные и изменяемое состояние;
|
||||
- когда создаются и уничтожаются долгоживущие ресурсы;
|
||||
- как устроена внутренняя реализация.
|
||||
|
||||
Место выполнения кода не меняет владельца. Компонент, провайдер, маршрут или точка запуска могут технически вызывать код ответственности, но не получают владение ею автоматически.
|
||||
Каждый файл принадлежит ближайшей модульной границе и реализует ответственность этого модуля. Место выполнения или вид кода не меняют владельца.
|
||||
|
||||
## Структурная модель
|
||||
|
||||
@@ -22,41 +22,58 @@ SLM описывает владение ответственностями вн
|
||||
SLM root
|
||||
└── слой
|
||||
├── модуль
|
||||
│ └── сегмент
|
||||
│ ├── сегмент
|
||||
│ └── вложенный модуль
|
||||
│ ├── сегмент
|
||||
│ └── вложенный модуль
|
||||
└── группа
|
||||
├── модуль
|
||||
└── группа
|
||||
└── модуль
|
||||
└── сегмент
|
||||
```
|
||||
|
||||
| Сущность | Назначение | Владеет ответственностью |
|
||||
|---|---|---|
|
||||
| Слой | Классифицирует код по архитектурной роли | Нет |
|
||||
| Группа | Классифицирует модули внутри слоя | Нет |
|
||||
| Модуль | Реализует одну самостоятельную ответственность | Да |
|
||||
| Группа | Навигационно классифицирует модули внутри слоя | Нет |
|
||||
| Модуль | Владеет одной самостоятельной ответственностью | Да |
|
||||
| Сегмент | Организует внутренности одного модуля | Нет |
|
||||
|
||||
Слой и группа находятся снаружи модульной границы. Сегмент находится внутри неё. Компоненты, хуки, сервисы, хранилища и другие детали реализации принадлежат ближайшему модулю-владельцу, если сами не образуют вложенный модуль.
|
||||
Вложенный модуль является обычным модулем, размещённым внутри родительского. Он владеет отдельно сформулированной подответственностью и создаёт следующий рекурсивный структурный уровень.
|
||||
|
||||
Слой и группа находятся снаружи модульной границы. Сегмент находится внутри неё. Framework-компоненты, Providers, Guards, hooks, stores, services и другой внутренний код не являются архитектурными сущностями SLM и принадлежат ближайшему модулю.
|
||||
|
||||
## Внутренняя реализация
|
||||
|
||||
Модуль может содержать любой код, относящийся к его ответственности. SLM ограничивает не набор framework-механизмов, а владение и наблюдаемую структуру:
|
||||
|
||||
- помимо опционального главного framework-файла в корне, остальные компонентные единицы располагаются на одном внутреннем уровне относительно модуля;
|
||||
- каталог компонентной единицы не содержит другие компонентные единицы или вложенные модули;
|
||||
- рекурсивная структурная вложенность создаётся только вложенными модулями;
|
||||
- помимо публичных фасетов, в корне находится не более одного главного implementation- или assembly-файла;
|
||||
- если главный файл нельзя определить уверенно, реализация размещается в сегментах.
|
||||
|
||||
Ограничение глубины framework-компонентов относится к файловой организации, а не к runtime-дереву фреймворка.
|
||||
|
||||
## Порядок проектирования
|
||||
|
||||
Архитектурное решение принимается от смысла к структуре:
|
||||
|
||||
1. Описать результат или поведение, за которое должен отвечать код.
|
||||
2. Определить одну причину изменения этой ответственности.
|
||||
3. Найти связанные данные, поведение, состояние и жизненный цикл.
|
||||
4. Назначить модуль владельцем и определить его внешних потребителей.
|
||||
1. Описать результат, который должен получить пользователь или приложение.
|
||||
2. Назначить модуль, который отвечает за этот результат.
|
||||
3. Определить, что модуль делает сам, а что получает от других модулей.
|
||||
4. Определить, кто использует результат работы модуля.
|
||||
5. Выбрать [слой](./layers.md) по роли ответственности.
|
||||
6. Спроектировать публичный API и допустимые зависимости [модуля](./modules.md).
|
||||
7. При необходимости организовать реализацию [сегментами](./segments.md).
|
||||
8. Только после этого выбрать физические пути и имена файлов.
|
||||
6. Спроектировать публичный API и допустимые [зависимости](./dependencies.md).
|
||||
7. При необходимости классифицировать модули [группами](./groups.md), организовать внутренний код [сегментами](./segments.md) и выбрать физические пути.
|
||||
|
||||
Например, Header сам определяет расположение шапки, отображение навигации и состояние мобильного меню. Текущего пользователя он получает от модуля `auth`, а `Button` и `Avatar` — от модулей `ui`. Если удалить Header, авторизация и UI-компоненты останутся нужны приложению, поэтому Header использует их, но не владеет ими.
|
||||
|
||||
Если ответственность или владелец не определены, файловая структура не может исправить архитектурную неопределённость.
|
||||
|
||||
## Логическая и физическая границы
|
||||
|
||||
Модуль не определяется наличием папки, `index.ts` или нескольких файлов. Его определяет самостоятельная ответственность и владение её контрактом, зависимостями, состоянием и жизненным циклом.
|
||||
Модуль не определяется наличием папки, `index.ts`, framework-компонента или нескольких файлов. Его определяет самостоятельная ответственность и владение её контрактом, зависимостями, состоянием и жизненным циклом.
|
||||
|
||||
После принятия решения модуль получает отдельную папку и публичные точки входа. Это обязательное физическое представление модульной границы, необходимое потребителям и автоматическим проверкам.
|
||||
|
||||
@@ -65,7 +82,7 @@ SLM root
|
||||
- самостоятельная ответственность требует модульной границы;
|
||||
- отдельная папка сама по себе не доказывает наличие модуля.
|
||||
|
||||
Пути сопоставляются со слоями, группами, модулями и сегментами в стайлгайде или конфигурации конкретного проекта. Имя пути не меняет нормативный смысл сущности.
|
||||
Пути сопоставляются со слоями, группами, модулями, вложенными модулями и сегментами в стайлгайде или конфигурации конкретного проекта. Имя пути не меняет нормативный смысл сущности.
|
||||
|
||||
## Область применения
|
||||
|
||||
@@ -73,12 +90,14 @@ SLM применяется внутри **SLM root** — границы стру
|
||||
|
||||
Архитектура определяет:
|
||||
|
||||
- роли слоёв и допустимые направления зависимостей;
|
||||
- роли слоёв и допустимые межслойные направления;
|
||||
- владельцев самостоятельных ответственностей;
|
||||
- публичные границы модулей;
|
||||
- общий ацикличный граф модулей;
|
||||
- назначение групп и сегментов;
|
||||
- внутреннюю глубину framework-компонентных единиц;
|
||||
- владение состоянием и жизненным циклом ресурсов.
|
||||
|
||||
SLM не задаёт обязательный поток данных, полный файловый стайлгайд, фиксированный набор сегментов, правила монорепозиториев или обязательную внутреннюю форму каждого модуля.
|
||||
SLM не задаёт обязательный поток данных, конкретный framework, фиксированные имена сегментов, правила монорепозиториев или полный файловый стайлгайд.
|
||||
|
||||
Нормативный смысл терминов находится в [терминологии](../reference/terminology.md). Точные блокирующие требования объявлены только в [реестре правил](../rules/registry.md).
|
||||
|
||||
Reference in New Issue
Block a user