BLoC — ce este, Business Logic Component în Flutter

Autor: IT Sectr Publicat: 2026-02-19 Timp de citire: 7 min

BLoC (Business Logic Component) — model de gestionare a stării pentru Flutter, prezentat de Google în 2018 la DartConf. BLoC separă logica de afaceri de interfața utilizatorului prin fluxuri reactive (Stream): UI trimite un Event, BLoC îl procesează și returnează un nou State prin Stream. Conform datelor pub.dev, pachetul flutter_bloc a strâns peste 11 mii de aprecieri și este utilizat în mii de aplicații Flutter.

Principalele puncte

  • Event — semnal de intrare care descrie acțiunea: apăsarea butonului, încărcarea datelor
  • State — stare de ieșire a UI: date încărcate, eroare, încărcare
  • Bloc — clasa principală care primește Event și returnează State prin Stream
  • Cubit — versiune simplificată a Bloc fără Event, care apelează funcții direct
  • BlocProvider — widget Flutter pentru injectarea Bloc în arborele de widgeturi

Ce este BLoC?

BLoC (Business Logic Component) — model arhitectural pentru Flutter în care logica de afaceri este extrasă într-o clasă separată, izolată de UI. BLoC primește datele de intrare printr-un flux de evenimente (Event) și emite datele de ieșire printr-un flux de stări (State). Stratul de prezentare (Widget) doar se abonează la fluxul State și afișează UI, fără a executa niciodată logica de afaceri direct.

Conceptul BLoC se bazează pe programarea reactivă și modelul Observer. Fiecare componentă BLoC este un modul separat cu un contract clar: setul de Event (ce se poate întâmpla) și setul de State (ce poate fi afișat) sunt cunoscute. Dezvoltatorul nu poate schimba "accidental" starea din UI — doar printr-un Event specific. Acest lucru face codul predictibil și testabil.

Conform sondajului Flutter Community 2025, BLoC ocupă locul doi în popularitate printre soluțiile de gestionare a stării în Flutter după Provider. Avantajele principale: tipizare strictă, izolarea logicii, suport încorporat pentru Stream, ecosistem bogat de utilități (BlocProvider, BlocListener, BlocSelector).

Arhitectura BLoC: Event → Bloc → State

Arhitectura BLoC se construiește în jurul a trei entități: Event (intrare), Bloc (procesor) și State (ieșire). Widget trimite Event prin metoda add(). Bloc primește Event în metoda mapEventToState sau on<Event>, execută logica de afaceri și emite un nou State prin yield. Widget primește State prin Stream și se redesenează.

Dart
abstract class CounterEvent {}

class Increment extends CounterEvent {}
class Decrement extends CounterEvent {}

class CounterBloc extends Bloc<CounterEvent, int> {
  CounterBloc() : super(0);

  @override
  Stream<int> mapEventToState(CounterEvent event) async* {
    if (event is Increment) {
      yield state + 1;
    } else if (event is Decrement) {
      yield state - 1;
    }
  }
}

Siguranța tipurilor: Bloc este parametrizat cu două tipuri — Event și State. Compilatorul Dart verifică că Widget apelează doar Event-urile declarate, iar Bloc returnează doar State-urile declarate. Erorile de execuție de tip "Acțiune necunoscută" sunt excluse.

Close și Dispose: Bloc implementează interfața Closeable. La distrugerea widgetului, Bloc închide automat Stream prin metoda close(). Scurgerile de abonamente reactive sunt imposibile — BlocProvider gestionează ciclul de viață al Bloc, legându-l de un route sau o pagină.

Bloc și Cubit: comparație

Cubit — implementare simplificată a Bloc fără Event, introdusă în pachetul flutter_bloc 6.0. Cubit declară metode direct în loc de clase Event: increment(), fetchData(). Intern, Cubit folosește același mecanism bazat pe Stream, dar ascunde stratul Event. Aceasta reduce boilerplate-ul cu 40-50% pentru scenarii simple.

CaracteristicăBlocCubit
Clase EventObligatoriiNu sunt necesare
BoilerplateRidicatScăzut
Urmărirea acțiunilorPrin tipul EventDoar numele metodei
Potrivit pentruScenarii complexeStări simple
AnaliticăAutomată prin EventManuală

Când să alegeți Cubit: stare cu 2-3 variante (loading, loaded, error), formulare simple, contoare, stări UI (deschis/închis). Când Bloc: logică de afaceri complexă cu multiple acțiuni: finalizare comandă, autentificare, sincronizare date. Bloc oferă trasabilitate detaliată a fiecărei acțiuni prin Event — fiecare apel este înregistrat în BlocObserver.

BlocObserver — observator global care urmărește toate Bloc și Cubit-urile din aplicație. Permite înregistrarea Event, State, erorilor și tranzițiilor. Este suficient să conectați o singură instanță: Bloc.observer = AppBlocObserver(), iar întreaga trasabilitate a stării aplicației este disponibilă centralizat.

BlocProvider și BlocBuilder

BlocProvider — InheritedWidget din flutter_bloc care furnizează Bloc widgeturilor copil. La inițializarea widgetului, BlocProvider creează un Bloc, iar la distrugere — îl închide automat prin close(). BlocProvider poate fi plasat la nivelul MaterialApp (Bloc global) sau la nivelul unui route specific (Bloc local).

Dart
BlocProvider(
  create: (context) => CounterBloc(),
  child: Column(
    children: [
      BlocBuilder<CounterBloc, int>(
        builder: (context, state) => Text('$state'),
      ),
      ElevatedButton(
        onPressed: () => context.read<CounterBloc>().add(Increment()),
        child: Text('+'),
      ),
    ],
  ),
)

BlocBuilder — widget care reconstruiește UI la fiecare nou State. BlocListener — pentru efecte secundare (procesare unică a State, fără reconstruire UI): afișarea unui SnackBar, navigarea la un alt ecran. BlocConsumer — combinație între Builder și Listener pentru cazurile când sunt necesare atât reconstruirea, cât și efectele secundare. BlocSelector — pentru reconstruire selectivă doar la modificarea unui câmp specific al State.

MultiBlocProvider — widget pentru BlocProvider-uri imbricate fără a crește nivelul de imbricare. O aplicație Flutter cu 10-15 Bloc-uri folosește MultiBlocProvider la nivel rădăcină pentru înregistrarea tuturor Bloc-urilor disponibile în întreaga aplicație: AuthenticationBloc, CartBloc, SettingsBloc.

Testarea BLoC

BLoC se testează izolat, fără widgeturi Flutter. Este suficient să importați pachetul Dart flutter_test și pachetul bloc_test. Scenariul de test: creați un Bloc, adăugați un Event, verificați State. blocTest — utilitar care automatizează secvența: build → act → expect.

Dart
blocTest<CounterBloc, int>(
  'emits [1] when Increment is added',
  build: () => CounterBloc(),
  act: (bloc) => bloc.add(Increment()),
  expect: () => [1],
)

Mocking: BLoC care depinde de un depozit sau API se testează cu mock-uri prin mocktail. Depozitul este mock-uit la nivel de abstractizare, Bloc primește dependențele mock-uite prin constructor. Hydrated Bloc — extensie pentru salvarea/restaurarea automată a stării în stocare locală. Se testează cu HydratedBlocStorage și stocare temporară în fișiere.

BLoC în producție

Dosare și fișiere: structura tipică a unui proiect Flutter cu BLoC: bloc/counter_bloc.dart, bloc/counter_event.dart, bloc/counter_state.dart. Pentru 30+ ecrane, se recomandă gruparea pe funcționalități: features/auth/bloc/, features/cart/bloc/. Fiecare Bloc — fișier separat, fiecare Event și State — fie în fișiere separate, fie într-unul singur cu Bloc.

Performanță: BLoC nu creează suprasarcină pentru Stream-urile goale. BlocBuilder folosește buildWhen pentru filtrarea redesenerilor — widgetul se actualizează doar la modificarea unei condiții specifice. Close garantează că Bloc-urile inactive nu consumă memorie. Conform Flutter DevTools, BLoC adaugă mai puțin de 1% la dimensiunea pachetului.

Migrarea de la Provider: BLoC coexista ușor cu Provider în același proiect. Migrare treptată: mai întâi se înlocuiesc cele mai complexe Provider-uri cu Bloc, apoi restul. BlocProvider este compatibil cu arborele Provider: widgeturile vechi pot folosi Provider, cele noi — BlocProvider, în aceeași aplicație.

Întrebări frecvente

Cu ce se deosebește BLoC de Provider în Flutter?

BLoC folosește Event + Stream pentru izolarea logicii de afaceri și tipizare strictă. Provider — un înveliș peste InheritedWidget pentru injectare simplă a dependențelor și ChangeNotifier. BLoC este mai potrivit pentru scenarii complexe cu multiple stări, Provider — pentru starea UI locală. BLoC necesită mai mult boilerplate, dar oferă trasabilitate completă prin Event.

Ce este Hydrated Bloc?

Hydrated Bloc — extensie din pachetul hydrated_bloc care salvează automat ultimul State în stocare locală (implicit Hive). La repornirea aplicației, Bloc restaurează starea salvată în loc de cea inițială. Aceasta rezolvă problema persistenței fără apel manual de salvare: autentificare, coș, setări se salvează automat între sesiuni.

Cum se gestionează erorile în BLoC?

O eroare în BLoC este gestionată prin try-catch în interiorul mapEventToState sau on<Event>. La eroare, Bloc returnează o State de eroare: yield LoadError(error.message). În UI, BlocListener sau BlocConsumer verifică State pentru tipul de eroare și afișează un SnackBar sau dialog. BlocObserver înregistrează global toate excepțiile negestionate.

Poate fi folosit BLoC cu alte framework-uri?

BLoC — model specific Flutter, deoarece utilizează Dart Stream și widgeturi Flutter. Conceptul Event → Bloc → State poate fi adaptat pentru AngularDart și Server-side Dart, dar ecosistemul principal (BlocProvider, BlocBuilder, BlocObserver) este legat de Flutter. Pentru React Native utilizați Redux sau MobX, pentru SwiftUI — Combine + MVVM.

Ce să alegem: Bloc sau Cubit?

Cubit — pentru stări simple (contor, toggle, formular cu 2-3 câmpuri). Bloc — pentru logică complexă (flux de știri, finalizare comandă, autentificare). Regula principală: dacă este necesară trasabilitatea fiecărei acțiuni (Event) pentru analitică sau depanare — Bloc. Dacă sunt suficiente metode care modifică starea — Cubit. Ambele modele coexistă în același proiect.

Rezumat

  • BLoC — model de gestionare a stării Flutter prin Event → Stream → State
  • Event — acțiune (clic, încărcare), State — reacție (date, eroare, încărcare)
  • Cubit — versiune simplificată fără Event, cu până la 50% mai puțin boilerplate
  • BlocProvider — injectarea Bloc în arborele de widgeturi cu close automat
  • BlocObserver — monitorizare globală a tuturor Bloc și Cubit din aplicație
  • Hydrated Bloc — persistență automată a stării prin Hive
  • blocTest — utilitar pentru testarea modulară a Bloc cu izolare de Flutter

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și