kitsuniru / streamed_controller

A opinionated predictable state management library with prebuilt concurrency helpers that implement the Business Logic Component design pattern without complexity of BLoC.
MIT License
1 stars 0 forks source link

Can you give a critique of Bloc? #1

Open haf opened 9 months ago

haf commented 9 months ago

It would be useful to understand what makes bloc "complex" in your opinion and why this is better.

For me bloc is hard to use in a very concurrent setting, because I have to manually deal with interleavings of event handlers' execution and there's no way to specify an event B has to happen before event A is handled (if they are both concurrent). Also, because Bloc want to be the State behind your Widgets, you end up mixing some amount of business logic with UI state management logic.

kitsuniru commented 9 months ago

thanks for your question, @haf

on\<T>

first of all, bloc's concurrency by default is based on concurrent handler, it means that all incoming events from outside handles without any ordering, this may cause data race (or maybe, state race) issue example: 1) user press 'login', state flow: Idle -> Loading ---------4sec-------------> Failed 2) user press 'login' again, during loading (idk how, but let's imagine that this's possible) Idle -> Loading -------------------5sec-----------------> Success

so, user will get next state flow's: Idle -> Loading ---------4sec-------------> Failed Idle -> Loading -------------------5sec-----------------> Success

let's merge it and we will get Idle -> Loading ----------------4sec------> Failed ---1sec--> Success

this means that user will receive popup/alert/etc about error during signing in and after 1sec will receive message/action about successfull login

that's a first problem of bloc: multiple event handlers: on<T>

in my opinion, we should have only one active event handler, but bloc doesn't bounds them to single value

Stream API

next problem is Stream API instead of Listenable API

in flutter we have many useful widgets to work with Listenable's: 1) ListenableBuilder 2) AnimatedBuilder 3) ValueListenableBuilder (aka BlocBuilder) 4) InheritedNotifier (aka BlocProvider)

-- all of them give us possibility not to use third-party solutions like a provider, because, for example, InheritedNotifier is basically Provider widget but only for Listenable's

and at the same time Stream API have only StreamBuilder from the sdk also, native Stream's doesn't caches last value (only third-party solutions. like rxdart give us possibility to do this) by my opinion - it really ties our hands

i think, Stream API as a base for a bloc is a historical mistake, things will be better if bloc was built over Listenable

but, please, dont think that im a hater of bloc, i see there's a 2 pros of bloc: 1) standardized in the community - most of the projects (where i was involved) were using bloc 2) works without Flutter - to be honest, i can't comment that, things will be better if dart-sdk would contain 'Listenable' abstraction in itself, but unfortunately it doesn't currently contain