В этом стриме мы разберем готовую архитектуру 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 архитектуре нужно отметить, что в ней подразумевается в первую очередь первый тип переиспользования слайсов. Некоторые вещи из инфраструктурного слоя могут повторно использоваться в других проектах, при правильном проектировании. Но на практике такое стремление сильно ограничивает разработку и только очень небольшой процент базовых и очень абстрактных вещей можете быть повторно использован между проектами.

Поэтому работая с данной архитектурой в первую очередь следует рассматривать повторное использование слайсов внутри проекта.