I'm Building Taskito
I'm Building Taskito
Get it on Google Play Download on the App Store

Introduction to MVVM architecture in Android


MVVM stands for Model-View-ViewModel. Google has started recommending usage of this architecture to develop android apps and have provided a lot of new tools and frameworks to support implementation of this architecture. ViewModel and LiveData being the basics to implement it. Google is also working towards providing support to integrate these components seamlessly with android activity and fragment lifecycles. Although the current state of these tools is not ideal, it’s pretty stable and works well.

Understanding MVVM

Here, I have added a diagram of the MVVM pattern flow and how it binds everything together.

MVVM flow diagram MVVM flow diagram

  • ViewModel interacts with the Model (API, database, etc) to get the necessary data and updating it if required.
  • ViewModel exposes data streams of the state. Any component can subscribe to the stream and receive updates regarding the state. Here, a view component (activity, fragment, viewgroup, etc) will subscribe to the exposed data streams. On every update, the view component will render itself.
  • When user takes a certain action (eg. save a note, etc), the view would ask the ViewModel to perform certain actions. The ViewModel would update the Model, create a new state and dispatch it to the data streams.
  • View component would receive the update and render the updated state.

The idea behind MVVM pattern is quite simple but the implementation is bit nuanced which we will dive into the upcoming posts.

Advantages of MVVM

Before the introduction of MVVM, a lot of apps were developed using MVP architecture. Although MVP is okay, MVVM has significant advantages over MVP pattern. Here are some of the key advantages of MVVM over MVP.

Coupling

View and Presenter are tightly coupled in MVP. As per the pattern, both View and Presenter have a contract (usually defined via interfaces). It’s difficult to reuse these contracts with other views or presenters. This problem does not arise in MVVM pattern as ViewModel exposes only data streams and it’s up to the view to decide how to use this data. With this pattern, a view can easily use multiple view models and a view model can be reused with multiple views.

Unit testing

Unit testing in Android is usually quite painful. To make the MVP unit-testable, we create an interface for the View and use a mocked instance for unit tests. Since a ViewModel is not tied to any View component in MVVM, it’s much easier to unit test the ViewModel without having to worry about the view. Since Google is supporting MVVM officially, they have also provided a lot of tools to perform unit tests with MVVM and LiveData so that’s a plus.

Unidirectional

There’s a bi-directional data flow between View and Presenter in MVP. To set the data to the view, it usually calls view.setUser(user) and to update certain data, view would call presenter.update(data) which creates a bi-directional data flow. In MVVM, we would still require to call some method on the ViewModel when the user interacts with the View, but we can create an indirect link which does not directly interact with the ViewModel. Instead of calling viewModel.update(data), we can use viewModel.dispatch(action) and the ViewModel or some other component inside the ViewModel handles the action and updates the state. With a Redux like approach, we can make MVVM unidirectional.

Reactive

MVP is passive so any change in model has to be manually updated by the Presenter. On the other hand, the recommended approach with MVVM is to expose data stream (eg. LiveData). Once the data is updated, all the subscribers of the data stream will receive the updates.

Apart from these benefits, one of the major benefit is that Google is officially supporting MVVM architecture pattern and actively providing better tools and frameworks.

References

Here are some useful links that talk about MVVM architecture pattern.