Ответ
В своих Flutter-проектах я использовал несколько паттернов, выбор которых зависит от масштаба и сложности приложения:
-
Provider + ChangeNotifier: Это был мой основной выбор для средних по сложности коммерческих проектов. Он идеально сочетает простоту и мощность, будучи официально рекомендованным командой Flutter. Я создавал модели, расширяющие
ChangeNotifier, и использовалConsumerилиProvider.ofдля реактивного обновления UI.// Типичная модель в таком подходе class AuthService extends ChangeNotifier { User? _currentUser; User? get currentUser => _currentUser; Future<void> login(String email, String password) async { // ... логика запроса к API _currentUser = fetchedUser; notifyListeners(); // UI, слушающий эту модель, перестроится } } -
BLoC (с библиотекой flutter_bloc): Применял для проектов со сложной бизнес-логикой, где важно чёткое разделение ответственности и тестируемость. Паттерн основан на потоках (
Stream) и концепциях Event -> State.// Простой BLoC для счётчика class CounterBloc extends Bloc<CounterEvent, int> { CounterBloc() : super(0) { on<Increment>((event, emit) => emit(state + 1)); on<Decrement>((event, emit) => emit(state - 1)); } } // В UI: BlocBuilder<CounterBloc, int>(builder: (context, count) => Text('$count')) -
Clean Architecture (с Riverpod): Для одного крупного долгосрочного проекта мы выбрали Clean Architecture, чтобы изолировать бизнес-правила (Domain) от деталей реализации (Data, Presentation). В качестве state-менеджера использовали Riverpod, так как он предоставляет отличную типобезопасность, тестируемость и не зависит от
BuildContext.// Provider в Riverpod (уровень Data/Presentation) final userRepositoryProvider = Provider<UserRepository>((ref) { return UserRepositoryImpl(ref.watch(apiClientProvider)); }); final currentUserProvider = StateNotifierProvider<UserNotifier, User?>((ref) { return UserNotifier(ref.watch(userRepositoryProvider)); }); -
MVVM: Часто реализуется "из коробки" с
ChangeNotifier(как ViewModel) иValueListenableBuilder. Это интуитивно понятный паттерн для разделения UI и логики представления.
Мой общий принцип: начинать с Provider для скорости разработки, а для более сложных сценариев переходить на BLoC или Clean Architecture с Riverpod, чтобы обеспечить долгосрочную поддерживаемость кода.