I'm creating a new app with Flutter, and I'm trying to design it, separating the business logic from the view.
I've read about Bloc and MVVM (I know there are other patterns but these were the ones I preferred), but I don't understand the differences between them. They look pretty much the same to me.
Does anyone can help me understand them?
If you know about the MVVM (Model-View-ViewModel) pattern, the BLoC is the replacement for ViewModel. The BLoC is responsible for managing the state for View, and the Model (or Repository) helps the BLoC to access data no matter local or remote. In Flutter, there is no data binding.
MVVM is better than MVC/MVP because of its unidirectional data and dependency flow. Dependency is one way, thus it is a lot easier to decouple it when we need to. It is also easier for testing. All my projects(written in Kotlin for Android app) are based on MVVM.
MVVM separates the different components of the development process into three categories, model, view and ViewModel. This typically involves code markup or graphical user interfaces (GUI). MVC, or model-view-control is a way developers separate programs into these three components.
So here, we can compare the StreamBuilder in Bloc with Consumer in Provider. The difference is that StreamBuilder listens to the stream and fetches the model on every change to rebuild the widget. But Consumer listens as soon as notifyListeners() executes inside the provider class.
Looking at this illustration for MVVM (source):
You can see that there are seperate data and business logic models. However, using BLoC there is not really a distinction like that. The classes that handle the business logic also handle the data, which can also apply to MVVM.
To be fair, there really is not much of a difference. The key part to take away is the same for both: Isolating the business logic from the UI. Hence, the implementation of either of the two will look very similar, i.e. using Stream
's and StreamBuilder
's.
Additionally, there are packages that make working with Stream
's easier, e.g. rxdart
which is what the Flutter team uses as far as I am concerned.
They are not quite the same, actually... MVVM implies databindings between the view and the viewmodel, which means, in practice, the view objects mostly are the ones commanding the viewmodel. MVVM seems to me a simplification of MVC, to show the model "as is" behind the scenes. For example, Xamarin largely uses MVVM and the controls on the screen like checkboxes, textinputs, etc, all do modify the modelview behind the scenes.
You may already starting to see a problem here: if you change the UI you may have to change the MV as well. Suppose you have an entry number that must be between 0-255, where do you put this logic? Well, on MVVM you put this logic on the view. But you must put these locks on the modelview as well to guarantee data safety. That means a lot of code rewriting to do the same thing. If you decide to change this range, you have to change in two places, which makes your code more prone to errors. Disclaimer: there are workarounds for this but is far more complicated than it should be.
On the other hand, BLoC works by receiving events and emitting states. It doesn't care (although it may) from where the event came from. Using the same example from the above, the view would signal an event to the bloc/controller with "hey, my number changed!", the bloc then would process this new event and, if suitable, emit a signal to the UI: "hey UI! You should change! I have a new state for you!". Then, the UI rebuilds itself to present those changes.
For me, the advantage of BLoC over MVVM is that the business logic can be entirely decouple from the view, which is overall a better way to do things. As our modern software development requires more and more changes in the UI (being different screen sizes, densities, platform, etc.), having the UI side decoupled from the models are a fantastic feature to code reusability.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With