Simplifying Android Architectures for Developers — MVC, MVP, MVVM, Clean, MVI , VIPER— part 3: MVVM
MVVM
Theory
I believe that was the first step done by google in some android architecture direction. At Google I/O 2017, they announced ViewModel. Before that point, we had some tools provided by the community to make easy some android architecture adoption. But now we have a specific tool provided by Google. That architecture choice never was mandatory, but the fact of the ViewModel was provided by Google made it become too popular. Beyond that, that architecture really works.
So, here we have 3 layers again:
MODEL (Exactly like in MVC, MVP)
The model contains Databases, business rules, and access to external resources.
VIEW
I'd like to remember you of the responsibility of this layer on MVP Architecture.
This layer is responsible to update UI and receiving UI triggers like a user click, or some life cycle event, and requesting information from the Presenter Layer.
Here will be too similar, but obviously, our connector here will be the ViewModel layer(yes, this is just one layer) instead of the Presenter.
And additionally, here the ViewModel doesn't know our view. But our View observes changes in ViewModel. So, our View layer has one more responsibility: observe changes in ViewModel.
VIEW MODEL
This works too as a connector between View and Model.
The main change here is ViewModel has LiveData: This is another library released by google when they released ViewModel. For now, we have other similar options, but e will be focused only on LiveData.
Basically is a structure capable to receive and storing some kind of data, and notifying observers of this data when it is changed.
This flow grants all stuff that depends on that information will be always updated.
Practice
Model
I will skip this layer because this is exactly like what was implemented in the previous article (part 1) where a talked about MVC.
View
Note: In MVP we don't have to receive from our connector a not primitive data. But here, we received a Person object (lines 34 and 38), not just a person's name. So, our view has a dependency on our entity class, which is a model class. It happens because our LiveData (you will see when I show you the ViewModel) observes the object, not the field. We could avoid the kind of dependency splitting an Object for all its fields, but that would become hard to maintain your code, mainly if we think in an Object with many fields.
So, because of that, maybe you will have to put some ifelses in your view. Because your view will receive your complete object and will decide what gonna do with that.
View Model
Since the view model depends on a model, we have sent it an instance of our model. This is done by a Factory.
Note: Since our view is already observing the changes on LiveData, we don't have to do anything after changing the data value.
About the LiveData, by the pattern, we have a private field, like _data that belong to the type MutableLiveData, and the data that is the same field, but it is public and belongs to the type LiveData.
This approach grants for some class out of ViewModel that can observe the LiveData, but this data value is changed only inside this ViewModel because only there do we have a MutableLiveData.
You can check this project on GitHub. Remember to select the architecture that you wish to study on the build variants:
Simplifying Android Architectures for Developers — part 1: MVC
Simplifying Android Architectures for Developers — part 2: MVP
Simplifying Android Architectures for Developers — part 3: MVVM
Simplifying Android Architectures for Developers — part 4: Clean
Simplifying Android Architectures for Developers — part 5: MVI
Simplifying Android Architectures for Developers — part 6: VIPER