I chose this talk because I wanted a quick comparison of different presentation patterns (mainly MVP and MVVM) as understood and accepted by the Android community.
It’s about MV(C|P|VM) where the M and V stand for Model and View respectively.
The Model is the interface from which data is retrieved and through which data is modified.
The View is the interface that displays the data.
NB: this is from 2016, before Android Architecture Components was released. Any reference to “ViewModel” is not referring to this library, but rather the concept as described in MVVM.
For a brief introduction to the Android Architecture Components, check out the Android Dialogs episode with Lyla Fujiwara, where they discuss ViewModel and LiveData.
How do you apply Model-View-Controller in Android?
(4:00) Implementing MVC on Android often resulted in the Activity taking the role of both the View and the Controller.
(4:46) Rather, keep the Activity as the View, which can tell the Controller (a separate class) about user input.
What is the Controller? It’s the interface responsible for:
- updating the Model in response to user input
- notifying the View that it should update (the View then requests updated data from the Model)
(5:16) To avoid the Controller knowing about Android concepts, like the Activity or Fragment, create an interface for the View (
IView) that the Activity implements.
The Controller can keep a reference to
IView which can then be swapped out in unit tests.
Transitioning from MVC to Model-View-Presenter
(6:40) The View ends up knowing too much with references to both the Controller and the Model, and leads to large Activity or Fragment classes with a lot of logic.
(7:14) Let’s break the connection between the View and the Model. Let only the Controller interact with the Model:
The Controller can get data from the Model, apply any UI logic (e.g. formatting), and then tell the View what it should present.
This is essentially Model-View-Presenter.
The View and Presenter have a reference to each other. Since each one has its own interface, the interfaces and the Presenter implementation can live in a separate module without Android dependencies.
IView exposes methods that allow the Presenter to update the UI.
(I’m not sure there is much value in having an interface for the Presenter — since the
IView interface abstracts away the
Fragment, the Presenter doesn’t need to have Android dependencies to begin with and can be in any module.)
(8:20) The View tells the Presenter when it’s ready to display data by calling
Here, the Presenter can load data from the Model, apply any UI logic, then update the View:
The View also notifies the Presenter about user actions. Then the Presenter is responsible for deciding what should happen next — updating the Model or the View.
Transitioning from MVP to MVVM with Observables
(10:00) Looking at this from an event-based point of view, the Presenter produces data and the View consumes data.
Why should the producer (the Presenter) know about the consumer (the View)? The producer shouldn’t care.
Instead, the Presenter should emit data events, and anything that’s interested should be able to subscribe to this event stream.
So we can add another method that exposes a stream of events:
The View can subscribe to this:
(11:05) Now, the Presenter doesn’t call
IView.setName(String). In fact, the Presenter doesn’t need a reference to the View at all, so we can get rid of the
There’s no need to call
IPresenter.onLoad() either, because the View will subscribe to the event streams that the Presenter exposes as soon as it’s ready to display data.
We’re left with Model-View-ViewModel.
(11:25) MVVM was introduced by Microsoft to simplify event-based implementations of user interfaces.
The ViewModel gets the data from the Model, applies any UI logic, and emits UI state events to whatever subscribes to it — the View, the tests, or other classes (e.g. another ViewModel).
(12:17) Rather than exposing multiple event streams, like so:
the ViewModel should expose the complete UI state (or a model) for the View:
Differences between MVP and MVVM
(13:10) The Presenter has a reference to the View, telling it what to display. The View also has a reference to the Presenter so that it can notify the Presenter about any user actions.
In MVVM, the ViewModel does not have a reference to the View; it doesn’t know about it. The View has a reference to the ViewModel, so it can subscribe to event streams of UI models, and also notify the ViewModel about user actions.
For me, the biggest takeaway was getting a quick overview of these different presentation patterns and how they relate to each other.
(13:50) The talk also includes an overview on how you might implement MVP/MVVM in Android apps, highlighting that the Activity, Fragment or custom Android Views can all be the View from MV(P|VM).
(15:53) Florina continues by showing us how to decide what goes in the View and what goes in the Presenter/ViewModel.
If it contains UI logic, it needs to go in the Presenter/ViewModel because it needs to be tested.
(16:55) Florina talks about UI which can have parts that are co-dependent, like a form button that is only enabled when all the fields are filled in. She explains how you can approach this with:
- data persisted in the Model, consumed by multiple Presenters or multiple ViewModels
- composite Presenters
- multiple ViewModels, where one consumes the events of another
(18:13) When should the View tell the Presenter that it’s ready to start loading or when should the View subscribe to events from the ViewModel?
(18:37) How (and where) can we persist state from Presenters and ViewModels on configuration changes?
“Which one should you use? Actually, it doesn’t matter. What all these patterns do is create a common language between you and your team.”
Be consistent, don’t be dogmatic. Ask yourself these questions:
- Are your Android classes logic free?
- Can you unit test your classes?
- Do your classes do one thing and one thing only?
Not yet, but they will be soon. Thanks Florina!