๐งฉ BLoC Architecture Guide
Guide lengkap untuk implementasi BLoC (Business Logic Component) pattern di MStore Mobile dengan proper scope dan lifecycle management.๐ Prinsip Dasar
Siapa yang Memiliki State?
BLoC bukan sekadar โcontrollerโ โ dia pemilik state dan event lifecycle.Pertanyaannya bukan โdi mana paling mudahโ, tapi siapa yang bertanggung jawab mengelola durasi hidup state itu.
โ๏ธ Hierarki UI dan Scope yang Tepat
Tabel Scope BLoC
| Level | Contoh | Cocok untuk BLoC? | Alasan |
|---|---|---|---|
| App (root) | main.dart | โ Ya, tapi hanya global state | Auth, UserSession, Theme |
| Route / Feature | /sales, /inventory | โ IDEAL | BLoC punya domain boundary jelas |
| Page / Scaffold | SalesListPage | โ ๏ธ Bisa, jika state hanya untuk page itu | Hanya 1 page concern |
| Component / Widget | SalesCardWidget | โ TIDAK | BLoC akan hidup-mati tiap rebuild |
๐งฉ Best Practice BLoC Scope per Domain
Global / Persistent
Scope: Root (di MaterialApp)Contoh:
- AuthBloc
- SettingsBloc
- ThemeBloc
Feature-based
Scope: RouteContoh:
- SalesBloc
- InventoryBloc
- HRBloc
Ephemeral UI
Scope: Page / Widget StateContoh:
- FilterCubit
- TabIndexCubit
- DialogCubit
๐ง Struktur Ideal (Modular + Feature Scoped)
๐ง Implementation Pattern
โ CORRECT: Route-Level BlocProvider
- โ AuthBloc hanya hidup selama route aktif
- โ
Semua widget di bawah LoginPage bisa
context.watch<AuthBloc>() - โ Tidak membanjiri global scope
- โ Auto-disposed saat keluar route
โ ANTIPATTERN: Page-Level BlocProvider
- โ Setiap kali route direpush, SalesBloc direcreate
- โ Request API ulang
- โ State hilang saat navigasi antar tab
- โ Tidak bisa share state ke sub-page (
/sales/detail/:id)
๐งฎ MultiBloc Pattern
Jika satu feature butuh beberapa state domain:- โ Semua anak widget bisa akses multi-state
- โ Masih terisolasi dalam feature route
- โ Lifecycle otomatis dihapus saat keluar route
๐งฑ Decision Matrix
- Kapan taruh di Route
- Kapan taruh di Page
- Kapan taruh di Component
- State domain / API calls
- Perlu diakses antar sub-page
- Misal: Sales, Inventory, HR
- Lifecycle: Lives as long as route lives
โ Implementation Checklist
1
Define BLoC Scope
Tentukan apakah state ini:
- Global (auth, theme)
- Feature-level (sales, inventory)
- UI-only (filter, sort)
2
Create BLoC/Cubit
3
Register in DI
4
Provide at Route Level
5
Access in Widgets
๐ Architecture Summary
| Prinsip | Rekomendasi |
|---|---|
| Scope utama BLoC | Per feature route (domain boundary) |
| Scope global | Hanya untuk state universal (auth, theme) |
| Page/Component level | Gunakan Cubit, bukan BLoC |
| Lifecycle rule | โBloc lives as long as the feature route lives.โ |
| Konsekuensi baiknya | - Tidak recreate state - Modular domain boundary - Lebih mudah di test dan DI |
๐ก Key Takeaways
BLoC Domain
Di route-level (feature provider)Contoh:
/sales, /inventoryCubit Ringan
Di page/component levelContoh: Filter, Sort, Tab Index
Root BLoC
Hanya untuk global shared stateContoh: Auth, Theme, Locale
Never in Component
Jangan taruh BLoC di widget kecilAkan recreate setiap build
๐ Related Documentation
Mobile Architecture
Complete mobile architecture guide
State Management
State management patterns
Dependency Injection
DI setup dengan Injectable
Testing BLoC
Unit testing untuk BLoC
Best Practice: Selalu provide BLoC di route-level untuk proper lifecycle management dan avoid memory leaks.