В этом стриме мы разберем готовую архитектуру Feature-Sliced. Я рассмотрю ее свойства и логику построения с позиции архитектора. Выделю главные и второстепенные моменты. Рассмотрю логику рассуждения при разработке архитектуры, а так же общие архитектурные принципы, используемые в этой архитектуре.
На мой взгляд это пример легкой, адаптируемой к нуждам заказчика архитектуры. При разработке методологии учитывались вопросы управления техническим долгом, разделение ответственности, возможности наращивания команды разработчиков и другие важные вопросы проектирования.
На данный момент описание методологии не закончено, но основные принципы и понятия сформулированы и могут использоваться на практике.
Feature-Sliced - это многоуровневая архитектура построенная на следующих принципах:
На изображении ниже показана общая организация слоев. На данном изображении представлены не все слои, которые могут быть созданы в рамках приложения, но данная четверка является обязательной.
На первом этапе мы должны рассмотреть каким образом архитектура предлагает провести архитектурные границы и по ним проконтролировать уровень зацепления (Coupling). Это первый шаг построения любой архитектуры.
Далее следует распределение обязанностей и обеспечение связности самостоятельных частей архитектуры.
Особенностью является выделение слоя страниц (pages). Все дело в том, что это слоистая архитектура для построения фронтенд приложений. Веб-технологии ограничены особенностями работы браузера, поэтому в рамках архитектуры мы не можем игнорировать данную особенность. Более того, страничный подход хорошо ложится на привычную логику работы сайтов, что позволяет удобным образом декомпозировать SPA.
Основой веб-приложения часто является стейт-лесс протокол (http или https). Поэтому для веб-приложений рекомендуется использовать принцип "url - это отражение стейта". В данном случае маршрутизация должна выполняться на уровне приложения и учитывать не только имеющиеся страницы, но и позволять восстановить по url все необходимое окружение.
Наличие слоя приложения и нижележащих слоев говорит о том, что эта архитектура рассчитана исключительно на уровень "кода". В системном дизайне на диаграммах "приложение" является самым маленьким "кирпичиком". Отсюда мы можем объединить разработку Feature-sliced архитектуры с такими нотациями как С4.
Отдельно обращу внимание на сегментирование слоев, здесь есть некоторые интересные моменты:
С позиции приложения можно выделить следствия монолитной архитектуры:
Архитектура предлагет три уровня разделения:
Основой методологии являются три принципа:
Описание слоев:
В качестве основы проектирования выступает итеративный процесс анализа задачи "снизу-вверх". Порядок следующий:
└── src/
├── app/ # Layer: Приложение
| #
├── processes/ # Layer: Процессы (опционально)
| ├── {some-process}/ # Slice: (н-р процесс CartPayment)
| | ├── lib/ # Segment: Инфраструктурная-логика (helpers/utils)
| | └── model/ # Segment: Бизнес-логика
| ... #
| #
├── pages/ # Layer: Страницы
| ├── {some-page}/ # Slice: (н-р страница ProfilePage)
| | ├── lib/ # Segment: Инфраструктурная-логика (helpers/utils)
| | ├── model/ # Segment: Бизнес-логика
| | └── ui/ # Segment: UI-логика
| ... #
| #
├── widgets/ # Layer: Виджеты
| ├── {some-feature}/ # Slice: (н-р виджет Header)
| | ├── lib/ # Segment: Инфраструктурная-логика (helpers/utils)
| | ├── model/ # Segment: Бизнес-логика
| | └── ui/ # Segment: UI-логика
| ... #
| #
├── features/ # Layer: Фичи
| ├── {some-feature}/ # Slice: (н-р фича AuthByPhone)
| | ├── lib/ # Segment: Инфраструктурная-логика (helpers/utils)
| | ├── model/ # Segment: Бизнес-логика
| | └── ui/ # Segment: UI-логика
| ... #
| #
├── entities/ # Layer: Бизнес-сущности
| ├── {some-entity}/ # Slice: (н-р сущность User)
| | ├── lib/ # Segment: Инфраструктурная-логика (helpers/utils)
| | ├── model/ # Segment: Бизнес-логика
| | └── ui/ # Segment: UI-логика
| ... #
| #
├── shared/ # Layer: Переиспользуемые ресурсы
| ├── api/ # Segment: Логика запросов к API
| ├── config/ # Segment: Конфигурация приложения
| ├── lib/ # Segment: Инфраструктурная-логика приложения
| └── ui/ # Segment: UIKit приложения
| ... #
| #
└── index.tsx/ #
Напомню, что DDD строится на базе следующих принципов:
Единый язык (Ubiquitous Language) - выверенный набор непротиворечивых терминов из бизнес области. Очень часто на практике - это аббревиатуры.
Ограниченный Контекст (Bounded Context) - явно ограниченная область, в рамках которой существует модель предметной области. Контекст служит для разделение системы на части (модули, компоненты)
Контекст может быть не один, но в каждом контексте есть только один единый язык.
Предметная область (Domain) - это бизнес задачи и их окружение. Состоит из:
Пространство задач - набор задач для формирования смыслового ядра
Пространство решений - один или несколько ограниченных контекстов, набор конкретных моделей.
Карта контекстов - пространство решений в разрезе контекстов.
Данные понятие хорошо ложатся на создание бизнес-домена в рамках Feature-sliced архитектуры. Главное - формирование бизнес-домена.
Хочу особенно обратить внимание, что в описании архитектуры на уровне кода не может быть только бизнес-словаря. Архитектура должна не только решать проблемы, которые стоят перед бизнесом, но и помогать формировать единый язык общения в команде.
Идея DDD в формирования бизнес-словаря как "скрывает" технические вопросы построения решения, однако при конкретной реализации бизенс-логики разработчики должны понимать как бизнес-логику свести с "кодом". Поэтому формирование технического словаря в рамках архитектуры - это важная задача:
Feature-sliced вводит свой набор терминов, которые должны использоваться в рамках проектирования по данной методологии, это безусловный плюс архитектуры.
Как и любая архитектура, Feature-sliced выдвигает требование к проектированию слайсов, но сама методология не выдвигает никаких собственных ограничений, кроме общепринятых SOLID, GRASP и им подобных.
Так же архитектура не формулирует никак собственных принципов, предполагая, что они должны быть сформулированы при использовании архитектуры в контексте конкретной бизнес-логике.
Говоря о переиспользуемости, следует отметить два варианта повторного использования кода:
Говоря о том, что Feature-sliced архитектуре нужно отметить, что в ней подразумевается в первую очередь первый тип переиспользования слайсов. Некоторые вещи из инфраструктурного слоя могут повторно использоваться в других проектах, при правильном проектировании. Но на практике такое стремление сильно ограничивает разработку и только очень небольшой процент базовых и очень абстрактных вещей можете быть повторно использован между проектами.
Поэтому работая с данной архитектурой в первую очередь следует рассматривать повторное использование слайсов внутри проекта.