Какой паттерн чаще всего используешь в Flutter?

Ответ

В Flutter-проектах я чаще всего применяю паттерн BLoC (Business Logic Component) для управления состоянием. Он обеспечивает чёткое разделение бизнес-логики и представления, что упрощает тестирование и поддержку кода.

Практический пример с flutter_bloc:

// События
abstract class CounterEvent {}
class IncrementEvent extends CounterEvent {}

// Состояния
abstract class CounterState {
  final int count;
  CounterState(this.count);
}
class CounterInitial extends CounterState {
  CounterInitial() : super(0);
}
class CounterUpdated extends CounterState {
  CounterUpdated(int count) : super(count);
}

// BLoC
class CounterBloc extends Bloc<CounterEvent, CounterState> {
  CounterBloc() : super(CounterInitial());

  @override
  Stream<CounterState> mapEventToState(CounterEvent event) async* {
    if (event is IncrementEvent) {
      yield CounterUpdated(state.count + 1);
    }
  }
}

Почему выбираю BLoC:

  • Тестируемость: Логика изолирована от UI, можно тестировать без виджетов
  • Предсказуемость: Состояние изменяется только через события
  • Масштабируемость: Отлично работает в больших приложениях с множеством экранов
  • Инструменты: Хорошая поддержка в flutter_bloc с BlocBuilder, BlocProvider

Для простых виджетов или прототипов иногда использую StatefulWidget или Provider, но для production-приложений предпочитаю BLoC.

Ответ 18+ 🔞

Ага, слушай, вот реально интересный вопрос. Ты знаешь, в этих Flutter-проектах я, как правило, впариваю паттерн BLoC (Business Logic Component) для управления всей этой кухней с состоянием. Ну, ёпта, он просто берёт и раскидывает всё по полочкам: вот тут у тебя бизнес-логика, а вот тут — твоё представление. И тестировать потом — одно удовольствие, и поддерживать не пиздопроебибна, а вполне себе.

Вот, смотри, как это выглядит на практике с flutter_bloc:

// События
abstract class CounterEvent {}
class IncrementEvent extends CounterEvent {}

// Состояния
abstract class CounterState {
  final int count;
  CounterState(this.count);
}
class CounterInitial extends CounterState {
  CounterInitial() : super(0);
}
class CounterUpdated extends CounterState {
  CounterUpdated(int count) : super(count);
}

// BLoC
class CounterBloc extends Bloc<CounterEvent, CounterState> {
  CounterBloc() : super(CounterInitial());

  @override
  Stream<CounterState> mapEventToState(CounterEvent event) async* {
    if (event is IncrementEvent) {
      yield CounterUpdated(state.count + 1);
    }
  }
}

А теперь, блядь, почему я за него голосую двумя руками:

  • Тестируемость: Всё, логика сидит в своём углу, отдельно от UI. Можно её взять и протестировать, не таская за собой овердохуища виджетов. Просто красота.
  • Предсказуемость: Состояние меняется только через события, никаких левых мувов. Никакой «хитрой жопы», всё прозрачно.
  • Масштабируемость: Когда проект начинает распухать, а экранов становится как собак нерезаных, BLoC не сдыхает, а работает как часы.
  • Инструменты: Библиотека flutter_bloc — просто подарок. Там тебе и BlocBuilder, и BlocProvider — всё для комфортной жизни.

Ну а если делать какую-нибудь хуйню на коленке или прототип, то, конечно, можно и на StatefulWidget или Provider забить. Но если речь про серьёзное, production-приложение, где доверия ебать ноль к хаосу, то тут без вариантов — только BLoC, чувак.