MVVM vs Bloc patterns - mvvm

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?

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.

BLoC and MVVM seemed to be different when BLoC was introduced, but that differences faded away as BLoC implementations changed over time. Right now the only real difference is that BLoC doesn't specify a separate presentation logic and business logic, or at least it doesn't do it in an obvious manner. Presentation logic is the layer that understands interactions between UI elements and the business part of the application(Presenter job in MVP). Some BLoC implementations put presentation logic into BLoC's, some others into UI.
The NEW THING in BloC was that it should not expose any methods. Instead, it would only accept events through its exposed sink or sinks. This was for sake of code reuse between Angular Dart web apps and Flutter mobile apps. This concept was recently abandoned because we don't really write Angular Dart web apps and it is less convenient than regular methods. Right now Blocks in official BLoC package expose methods just like good ol' VM.
Some would say that BLoC should expose one Stream of complete state objects, while VM can expose multiple Streams, but this is not true. Exposing one Stream of states is a good practice in both approaches. At first, official Google BLoC presentations presented BLoCs implemented using multiple output Streams as well.
One interesting difference that seemed to be a thing was that BLoC should communicate via events not only with UI but also with different parts of the application. for example, it should receive an event after receiving Firebase notification or when Repository data changes. While this seems interesting I've never seen an implementation like that. It would be odd from a technical point of view (Repository would have to know about all BLoC's that are using it???). Although I am thinking about trying out such an implementation that would be based on EventBus but that's completely off topic :)

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.

Related

Best practices for routing based on App State in flutter (navigator 2.0)

I am stuck on the Architecture design of my App.
Assuming I have a Tristate (Error, Loading, Data), what is best practice in modern flutter (go_router, riverpod/provider, ...) for bringing this to life?
Two options:
One page (so no routing) and complex widgets, one shown for each tristate. Statemanagement based on e.g. provider which triggers a rebuild when the state changes.
Three pages (which allows for reuse based on e.g. different errors, data, etc) seems cleaner in design BUT now the router needs to decide based on what is happening in the Tristate
How can the three page way be implemented? A provider is not the way since this leads to all state being above the router, always. Further the loading page for example would need to navigate in the build method, which is only possible with hacks.
So while the three page design seems more clean to me (loading needs to know nothing about error needs to know nothing about data presentation) I feel like the implementation will not be clean in anyway.
How can the three page way be implemented? Or why should it not be? (Does anyone have some tips, pointers, articles or a best practice?)

Didier Boelens' Reactive Programming BLoC or how to implement an app wide BLoC

I was looking into quite a few pages to learn how to best implement an app wide bloc (for authentication, user management and initialization). I did not find so much and for a beginner regarding this level of bloc patterns I found it hard to identify a reasonable one.
The pattern by Didier Boelens explained here appears to be the most promising one.
Is it still a sound pattern (it is from 2018) or did the bloc library evolve in the meantime or did other patterns proved better/easier? What would be an easier but still favorable pattern?
The article starts with the bloc provided embedded in an InheritedWidget. If someone is familiar with this, could he/she explain please in simple words, why we need the bloc_event_state_builder and bloc_event_stream on top of bloc/event/state? Why can't I use a simple bloc/event/state pattern directly with the bloc_provider I read "Sometimes, handling a series of activities which might be sequential or parallel, long or short, synchronous or asynchronous and which could also lead to various results, can become extremely hard to program. You might also require to update the display along with the progress or depending on the states." but I guess I do not understand the orchestration of all elements of his pattern.
He defines a class BlocProvider<T extends BlocBase> extends StatefulWidget referencing an inherited widget. I guess I assume correctly that this will impact all my other page specific blocs where I used the out-of-the-box BlocProvider from the bloc package?!

Flutter best architecture patterns

I came from MVC and VIPER world and now I am new to Flutter cross-platform development. I really like declarative things it brings (like SwiftUI for example does as well). I see a lot of advantages in React architecture that Flutter uses to update UI with the most recent data. Though I still try to understand a conception of widgets. In my head, a word widget is more about UI things, but the documentation says that all in Flutter is a widget.
Let me highlight a simple example. Also, let's forget about declarative UI things.
In the iOS world using Objective-C or Swift, we usually separate a lot of layers such as data layer, UI layer, service layer, some helper layers and etc.
As you may notice we can't simply call these layers widgets, but looks like flutter can, but I may be wrong.
In the iOS world, I would like to use VIPER or some similar architecture pattern to separate different layers or add some services which request some data for me or do save it into the database.
What are the similar approaches or architecture patterns which I can use to follow best practice recommendations to achieve the best result, because as for me if we call some service which saves data to the database as a widget it's a bit strange. I would like to call it more service rather than a widget.
Do I need to write a widget for all such things? Or did I get it wrong?
Do I need to write widget for all such things? Or did I get it wrong?
Let me start by saying that flutter is flexible enough to allow you to adopt any pattern you have been using before and from MVVM, MVC, Redux, Mobx, Bloc, Provider, Riverpod etc pp there are many patterns out there which you can lean on.
Q: Do all services have to be widgets?
A: It depends.
Lets talk about "getting" the services first (dependency injection)
Using Widgets is just one way of doing dependency injection in Flutter which has the huge benefit of being scoped (only available to the children of the widget) and also of being disposed when this part of the widgettree is no longer needed (a bit over simplified).
There are other DI systems like getIt which don't rely on the widget tree - and you can do fancy stuff with getIt which is cumbersome to do in many of the others which rely on the build context to provide access to the object.
Imho in most cases you would not want to have your logic/ service in a widget but in a separate class which is then "provided" via a widget (e.g. using Provider, or by injecting it via getIt into the widget).
About "best practices":
There are many cool patterns which all have their pros and cons.
If you have a big team or the developers are changing often you might want to use a more rigid and biased system like BLOC (using the bloc library) - if you are solo or have enough time on your hands to do your own research, there might be patterns which better suit your needs. There is no one size fits all answer to this question.
For further research I would point towards the Flutter Architecture samples and the corresponding Github repo, there might be more examples in the Pull Request section

Which one is faster and performant Provider, bloc pattern or flutter_redux?

I need manage the states globally, I find a lot of way, in terms of managing the state by using Provider bloc pattern redux and etc.
But actually I dont know, which one is faster and performant?
Example: I am working on chat application, which I have to manage socket connection messages online offline status all as globally. the states need to be accessible from all screen, like ChatList screen, ChatBox screen and more...
I didn't test them all performance wise. And i do not think it will make much of a difference.
Provider works with inheritedwidget as scoped model i think.
I love the streams for the versatility of the data flow.... i think the key part for performance is to keep the rebuilding/painting of the widgets that require it at the lowest level of the tree.
get_it package should help you to keep those streams accessible everywhere, is a great simple package to keep neat model access, regarding the state management solution.
For instance, i believe that generating statelessstateful widgets instead of functions that returns widgets to make the layout, provides more performance, for the separation of buildcontexts.
In any case, the framework is super optimized and performant... if u run into any issue, u can easily track it down with the devtools and the community is very supportive.
Btw, take my basic reply with a grain of salt, as I've been only playing with flutter/dart for a week.

MVVM, UWP & Template 10 - Independency of model from view technology

My understading of MVVM is that View is responsible for user presentation logic, view-model for interaction logic and specific data transformation from UI independent model classes and model itself representing business domain from data point of view.
Key point is that model classes should be UI indenpendent.
Here comes UWP dev model and Template 10 BindableBase from which model classes are supposed to be derived from. It's quite handy but it ties the model to the specific UI implementation, namely UWP + Template 10.
I've got a data access layer spitting out domain object I want to feed directly as model to the UI. The domain is quite complicated. What I don't wan't to do is to reimplement data domain objects in the UI nor I wan't to pollute it with UI specific functions.
Any thoughts on this?
thank you
With all due respect, I think you might be thinking about this wrong.
The goal of MVVM is to separate your logic exactly like you describe. The intent of this separation is to simplify your code. Does this make view-models testable and separate concerns? Yes. But, I argue those are secondary goals to simplicity – which keeps your code manageable and maintainable.
Here’s another way to say it.
MVVM is a terrific approach for XAML applications. But, if MVVM did not make your view-models testable or separate concerns, MVVM is still a terrific approach for XAML applications because it simplifies code so much – smaller, simpler, and isolated.
Worth every penny.
You might argue that MVVM creates another layer of code that developers must understand before they can reason and contribute to the base. I would agree. But I would NOT conclude that MVVM is therefore impracticable. That added layer is trivial compared to the otherwise coupling of logic.
Now to your question.
Your data layer object, probably a data transfer object, is remarkably like your UI object, probably a model. Your developer instincts compel you to unite similar things through polymorphism, code generation, or interfaces to avoid added opportunity for bugs, complexity, and tests.
Consider this.
Objects created in your data layer are created for your data layer. Likewise, objects created in your UI layer are created for your UI layer. Similarity in structure is a byproduct of similarity in domain. Of course, they are similar: their intents, however, are not. Why would you merge them?
You already see the problem.
The only differences you have are, perhaps, a data layer constructor taking in some type of data reader and populating properties. That is perfect for the data layer but inappropriate for the UI layer. Your UI layer might have messaging events or a custom method to handle interaction. That is perfect for the UI layer but inappropriate for the data layer.
So, where’s the similarity?
I think developers, including myself, tend to see similar things as potentially identical. Your data-relevant features do not belong in your UI nor the other way. Instead what you need to do is to see the similarity but recognize that they are drastically different objects and don’t deserve to be made the same.
We’re lazy.
Duplicate code isn’t about tests and bugs. Not really. It’s about how we, as developers, are so obsessed with “Work smarter not harder” that we tend to look down on “working hard”. If an object is built for one layer it should be in that layer, and not shared by another. I strongly feel this way.
The right solution
The easiest solution is to let your DTO serialize on the data layer from DataLayer.Object and then deserialize it on the UI layer as UILayer.Model. This is the easiest and simplest approach and adequately allows you to coerce the data and the object API for the use by its unique layer.
This means there are two nearly identical objects: one on the data layer and one on the UI layer. But it does NOT mean there are two identical objects. They are not identical because they have functionality unique to each of the tiers, each of the layers.
What if there is no functionality?
It makes sense to wonder if this applies to objects and models that have no added functionality. I believe strongly that objects and models in any layer without added functionality are simply waiting for that functionality to be added. Should you assume there is none and build to that assumption, you force the future you or forthcoming maintenance developers to never add layer-specific functionality.
Does that matter?
I think it does. Why? Because layer-specific functionality in an object or model allows me to add sophistication (not complexity) to my architecture and implementation within the context of the data object or model, and not in an external construct like a manager, helper, or utility. There is no question that Type.DoSomething is easier than Helper.DoSomethingForType(Type).
I actually have three
Just so you know, here’s how I do it: in my projects, you and I probably have similar data layers/services. But, my UI layer actually has TWO models – not one. (Let’s pretend Users is the data type.) My UI layer has json.User and Models.User. The json.User is a bare bones structure, deserialized from my service, and matches the service object exactly. But my UI rarely needs the Service API surface/structure.
Service(DataLayer.User) > | net | > UI(json.User > Models.User)
So, then json.User is used to create Model.User, whose structure meets my UI layer’s needs exactly - including methods, events, and messaging constructs. I am free to change my Models.User as I add features to my UI, too - including merging data from other/new data services. Also, Model.User can implement INotifyPropertyChanged where the data layer objects and the json objects never would (or need to).
Consider this
If you keep your models separate and you keep one codebase from improperly influencing another, then any change in your database or change in your data service/layer does not REQUIRE a change in your UI layer, even if you change the API surface. Only json.User changes or tweaks to your deserialization hints in your UI layer are impacted. To me, this only makes sense.
But what about testing and bugs?
Tests rarely test structures. Data structures are the simplest thing you can add to a solution and rarely contribute to complexity. You can reason over a structure in about a second. You can reason over a method in about a minute. Structures have very little cost. They also have very little construction cost. If you copy/paste the initial structure from your data layer to your UI layer – that’s what we all do. But that is NOT duplicating code. It is just building similar objects appropriately decoupled.
That’s what I think.