Перейти к содержимому

Десегментация

Десегментация (также известная как горизонтальная нарезка или группировка по слоям) — это паттерн организации кода, при котором файлы группируются по их техническим ролям, а не по бизнес-доменам, которым они служат. Это значит, что код с похожим техническим назначением хранится в одном месте, независимо от бизнес-логики, которую он обрабатывает.

Этот подход популярен в метафреймворках вроде Next и Nuxt благодаря своей простоте: на нём легко начать, и он позволяет использовать такие функции, как автоимпорты и файловый роутинг:

  • Директорияapp
    • Директорияcomponents
      • DeliveryCard.jsx
      • DeliveryChoice.jsx
      • RegionSelect.jsx
      • UserAvatar.jsx
    • Директорияactions
      • delivery.js
      • region.js
      • user.js
    • Директорияcomposables
      • delivery.js
      • region.js
      • user.js
    • Директорияconstants
      • delivery.js
      • region.js
      • user.js
    • Директорияutils
      • delivery.js
      • region.js
      • user.js
    • Директорияstores
      • Директорияdelivery
        • getters.js
        • actions.js

Этот паттерн встречается и в кодовых базах на FSD в виде обобщённых папок:

  • Директорияfeatures
    • Директорияdelivery
      • Директорияui
        • Директорияcomponents/ ⚠️
          • …
  • Директорияentities
    • Директорияrecommendations
      • Директорияutils/ ⚠️
        • …

Источником десегментации могут быть и файлы. Файлы вроде types.ts могут объединять в себе несколько доменов, что усложняет навигацию и будущий рефакторинг, особенно в таких слоях, как pages или widgets:

  • Директорияpages
    • Директорияdelivery
      • index.ts
      • Директорияui
        • DeliveryCard.tsx
        • DeliveryChoice.tsx
        • UserAvatar.tsx
      • Директорияmodel
        • types.ts ⚠️
        • utils.ts ⚠️
      • Директорияapi
        • endpoints.ts ⚠️
pages/delivery/model/types.ts
// ❌ Плохо: смешанные бизнес-домены в обобщённом файле
export interface DeliveryOption {
id: string;
name: string;
price: number;
}
export interface UserInfo {
id: string;
name: string;
avatar: string;
}

Хотя на этой структуре легко начать, в крупных проектах она может привести к проблемам с масштабируемостью:

  • Низкая связность (low cohesion): изменение одной фичи часто требует правок файлов в нескольких больших папках, например pages, components и stores.

  • Сильная связанность (tight coupling): компоненты могут иметь неожидаемые зависимости, что приводит к сложным и запутанным цепочкам зависимостей.

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

Группируйте весь код, относящийся к конкретному домену, в одном месте.

Избегайте обобщённых имён папок, таких как types, components, utils, а также обобщённых имён файлов вроде types.ts, utils.ts или helpers.ts. Вместо этого используйте имена, которые напрямую отражают домен, который они представляют.

По возможности избегайте обобщённых имён файлов вроде types.ts, особенно в слайсах с несколькими доменами:

  • Директорияpages
    • Директорияdelivery
      • index.tsx
      • Директорияui
        • DeliveryPage.tsx
        • DeliveryCard.tsx
        • DeliveryChoice.tsx
        • UserInfo.tsx
      • Директорияmodel
        • delivery.ts
        • user.ts