Как разложить 200 файлов по папкам — один из ключевых вопросов в архитектуре мобильной разработки.
Обычно есть два классических ответа: feature-first и layer-first.
И оба подхода в чистом виде мне не очень нравятся.
1. Layer-first
ui / data / domain / ...
Идея хорошая: отделить слои, сделать зависимости понятными, не смешивать ответственность.
Но на практике под каждую фичу часто появляется папка в каждом слое.
В итоге, чтобы поработать с одной задачей, нужно развернуть почти всё дерево проекта:
ui/payments
domain/payments
data/payments
И дальше начинается бойлерплейт ради “clean architecture по канону”.
2. Feature-first
auth / profile / payments / ...
Здесь идея тоже хорошая: всё, что относится к фиче, лежит рядом.
Но на практике внутри каждой фичи часто снова появляются слои:
widgets / data / domain / state / models / utils
И получается странная ситуация: папок в проекте становится больше, чем файлов.
Главная проблема — не всё, что мы называем “фичей”, реально является маленькой фичей.
Например,
payments — это часто не одна фича, а целый функциональный блок:— список операций
— карточка редактирования
— фильтры
— статусы
— формы
— детали платежа
Если делать это как одну фичу — получаем монстра на десятки файлов.
Если дробить на много фичей — получаем десятки папок ради небольших кусков логики.
Тоже не очень.
К чему мы пришли в DartWay
Мы используем гибридный подход.
1. Всё универсальное выносим отдельно
То, что не относится к конкретной фиче, живёт отдельно:
—
ui_kit
— data layer— универсальный domain
— методы и extensions моделей
— общие инфраструктурные вещи
Это ближе к layer-first.
Например, весь базовый UI лежит в
ui_kit.2. Фича — это маленький изолированный кусок
Фича в DartWay — это не огромный раздел приложения.
Это компактный функциональный модуль.
Обычно внутри:
feature/
feature.dart
widgets/
logic/
В корне — один входной файл: виджет или extension, через который фича подключается снаружи.
Внутри:
—
widgets — функциональные виджеты—
logic — state, модели, хелперыГлавное правило:
во внутренности фичи нельзя ходить снаружи.
Если ты не работаешь с фичей, тебе не нужно открывать её вложенные папки.
Простая фича может содержать корневой файл и пару вложенных файлов.
Сложная фича — 3–5 виджетов и несколько файлов логики.
А большой блок вроде
payments становится не одной огромной фичей, а набором маленьких изолированных подфичей.Мне такой подход нравится тем, что он не заставляет выбирать между feature-first и layer-first.
Мы оставляем слои там, где они реально нужны, и используем фичи там, где важна локальность изменений.
Что думаете о таком подходе?
Как вы организуете код в проектах?