От переводчика
В течении полугодя изучаю язык программирования Dart и пробую писать простые интерфейсы на его фреймворке Flutter. Но когда приложение начинает занимать больше двух экранов или получать данные по сети, то встает вопрос о его структуре.Ниже превожу перевод одной статьи по этой теме, которая мне показалась полезной. По крайней мере познакомила меня с описанными подходами.
Структура Flutter-приложения: feature-first или layer-first
Какова наилучшая структура проекта для средних / больших Flutter-приложений?
Скорее всего, нет "правильного" ответа, который подходил бы для всех проектов.
Итак, давайте рассмотрим два популярных подхода, известных как "feature-first" и "layer-first", и узнаем об их различиях.
![Структура Flutter-приложения Структура Flutter-приложения](https://habrastorage.org/getpro/habr/upload_files/b3c/18c/732/b3c18c7328eca6a7e98a2231fedfe105.png)
Итак, что же нам следует выбрать?
Feature-first подход
Подход "функции внутри слоев" (сначала слой) не очень подходит для больших проектов с большим количеством функций.
Для любой заданной функции файлы, принадлежащие разным слоям, находятся далеко друг от друга, и нам приходится постоянно "перепрыгивать" между слоями.
Итак, что же нам следует выбрать?
Подход "функции внутри слоев" (сначала слой) не очень подходит для больших проектов с большим количеством функций.
Для любой заданной функции файлы, принадлежащие разным слоям, находятся далеко друг от друга, и нам приходится постоянно "перепрыгивать" между слоями.
Сперва, лучше всего рассмотреть структуру проекта применительно к архитектуре приложения.
Для справки, давайте рассмотрим эту высокоуровневую архитектуру, состоящую из четырех уровней:
‣ presentation ‣ application (опционально) ‣ domain ‣ data
![Разделение архитектуры приложения на слои Разделение архитектуры приложения на слои](https://habrastorage.org/getpro/habr/upload_files/ede/722/f84/ede722f84180b683a9c4d46903bf8a48.png)
Если ваше приложение достаточно сложное, у нас будет несколько функций.
И каждая фича (функция) может быть представлена группой классов, которые принадлежат к четырем слоям.
Фича — это сленг, название тех или иных признаков предмета, либо явления. Другими словами, это основная функция продукта, утратив которую пользователь расстроится и перестанет им пользоваться. (прим. переводчика)
В этом контексте у нас есть два варианта в отношении структуры проекта:
слои внутри объектов
объекты внутри слоев
![Отношение фич приложения к слоям архитектуры Отношение фич приложения к слоям архитектуры](https://habrastorage.org/getpro/habr/upload_files/cb4/5fc/c1a/cb45fcc1a7d7263a12acf58e55afe2ff.png)
Итак, что же нам следует выбрать?
Layer-first подход
Подход "фичи внутри слоев" (layer-first) не очень подходит для больших проектов с большим количеством функций.
Для любой заданной функции файлы, принадлежащие разным слоям, находятся далеко друг от друга, и нам приходится постоянно "перепрыгивать" между слоями.
![Пример структы приложения при подходе "Layer-first" Пример структы приложения при подходе "Layer-first"](https://habrastorage.org/getpro/habr/upload_files/63d/637/b41/63d637b415aa7747695049e59fc5e50a.png)
Но с подходом "слои внутри фичи" (feature-first) дела обстоят намного лучше.
Для данной фичи все нужные нам файлы находятся в одной и той же папке верхнего уровня.
И мы по-прежнему получаем хорошее разделение между слоями.
![Пример структы приложения при подходе "Feature-first" Пример структы приложения при подходе "Feature-first"](https://habrastorage.org/getpro/habr/upload_files/76e/10c/f3b/76e10cf3bfcc32a6baa0b8b0489ab0e8.png)
На практике все не всегда просто.
В начале проекта у вас может не быть хорошего представления о модели предметной области.
И это затрудняет четкое определение различных функций (фич) и соответствующую структуру проекта.
На этом этапе у вас может возникнуть соблазн создать по одной папке для каждого экрана вашего приложения.
Но это ошибка, потому что функции (фичи) - это не экраны.
Скорее, думайте о функциях как о функциональных требованиях, которые помогают пользователю выполнить определенную задачу.
![Она вам на Экран! Она вам на Экран!](https://habrastorage.org/getpro/habr/upload_files/904/b89/c92/904b89c923e02197c4feedc84fd781cc.png)
На практике я обнаружил, что изучение модели предметной области приводит к гораздо лучшему пониманию всей системы в целом.
Это помогает нам определить функции, которые нам нужны, чтобы позже мы могли "создать правильную вещь".
![Точка отсчета архитектуры приложения Точка отсчета архитектуры приложения](https://habrastorage.org/getpro/habr/upload_files/894/b2d/ca9/894b2dca9fb131834bd271eab8f0879e.png)
При таком подходе вы будете лучше подготовлены к тому, чтобы определить, какие виджеты, контроллеры, службы и репозитории относятся к каждой функции.
И в результате вы сможете лучше организовать свой проект.
![Отношение фич приложения к слоям архитектуры Отношение фич приложения к слоям архитектуры](https://habrastorage.org/getpro/habr/upload_files/9a5/c24/420/9a5c24420b13b364e89c7b985e389399.png)
Конечно, к крупным проектам предъявляются некоторые дополнительные требования (инфраструктура, производительность, организационная структура).
Эти проекты часто разделены на полностью независимые модули (пакеты), принадлежащие разным командам.
Но это отличная идея - с самого начала применять дизайн, ориентированный на предметную область.
Таким образом, в конечном итоге мы получим четкие границы между различными слоями и компонентами нашего приложения, что упростит управление зависимостями в дальнейшем.