Как ты выбираешь архитектуру для Flutter-проекта?

«Как ты выбираешь архитектуру для Flutter-проекта?» — вопрос из категории Архитектура, который задают на 29% собеседований Flutter Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Мой выбор архитектуры зависит от масштаба проекта, состава команды и долгосрочных требований к поддержке. Я отдаю предпочтение подходу, который обеспечивает тестируемость, разделение ответственности и лёгкость навигации по кодовой базе.

Мой типичный процесс выбора:

  1. Для прототипов или очень маленьких приложений: Использую простой StatefulWidget или базовый Provider для управления состоянием. Архитектура может быть условно разделена на папки screens/, widgets/, services/.

  2. Для средних и крупных production-проектов: Я выбираю комбинацию Clean Architecture (или её упрощённого варианта Domain-Driven Design) для структуры слоёв и Riverpod или Bloc для управления состоянием. Этот стек стал моим стандартом.

    • Clean Architecture обеспечивает чёткое разделение на Data, Domain и Presentation слои, делая код независимым от фреймворков и внешних библиотек.
    • Riverpod предоставляет исключительную тестируемость, безопасность (отсутствие BuildContext в бизнес-логике) и гибкость. Bloc — отличная альтернатива, особенно если команда уже с ним знакома, он хорошо структурирует поток событий и состояний.

Пример структуры проекта по Clean Architecture с Riverpod:

lib/
  src/
    features/
      auth/
        data/
          datasources/      # Локальные (Hive, SharedPrefs) и удалённые (API) источники
          models/           # DTO/Model от API
          repositories/     # Имплементация репозиториев
        domain/
          entities/         # Бизнес-сущности (User)
          repositories/     # Абстрактные классы-контракты
          use_cases/        # Интеракторы (LoginUseCase, LogoutUseCase)
        presentation/
          providers/        # Все StateNotifier, FutureProvider и др.
          widgets/          # Кастомные виджеты фичи
          pages/            # Экраны (LoginPage, ProfilePage)
    core/
      error/                # Обработка ошибок
      network/              # Настройка Dio
      theme/                # Тема приложения
      utils/                # Утилиты
  main.dart                 # Инициализация провайдеров и запуск приложения

Критерии, которые я взвешиваю:

  • Сложность бизнес-логики: Наличие сложных правил и состояний склоняет к Bloc/Riverpod + Clean Architecture.
  • Опыт команды: Если команда новая во Flutter, начинаю с Provider и простой слоистой структуры, постепенно усложняя.
  • Требования к тестированию: Clean Architecture позволяет легко тестировать Use Cases и Repository изолированно, без зависимости от Flutter.
  • Долгосрочность: Для долгосрочных проектов вложение времени в продуманную архитектуру окупается на этапах расширения и рефакторинга.