Understanding MVVM on Android Tutorial 01 – MVC vs MVP vs MVVM
As an android developer, you may have been asked by an employer/client to implement an architecture pattern when developing your app. Examples of commonly used patterns are MVC, MVP and MVVM, with most Android developers choosing either the MVP or MVVM pattern. However, there is a lot of discrepancy and confusion on how to implement these patterns “correctly” and I know a lot of developers have been struggling with the MVVM pattern due to so many contradictory or confusing approaches. This post is my attempt to demonstrate a “really simple” but detailed step-by-step demonstration of using the MVVM pattern in an Android app. Through the course of the series, we will be developing an app which accesses a REST API and displays the received data in the app. We will also be making using of some popular Android libraries like GSON, Retrofit2, RXJava and Dagger2.
What is a software architecture pattern anyway?
A software architecture pattern can be regarded as a set of rules to be applied when developing a software application. These rules include a list of objects to be used in the application and most importantly some constraints about how these objects will interrelate and interact with each other. Some of the major benefits of software architecture patterns include; making it easier for multiple developers to collaborate and maintain the same code base by introducing a level of standardization in how the code is written, helping to decompose problems into smaller pieces, and once all the developers on a project are over the learning curve it can make the development process much faster.
Now that we know what a software architecture pattern is, lets discuss three of the most commonly used patterns: MVC (Model-View-Controller), MVP (Model-View-Presenter) and MVVM (Model-View-ViewModel).
The patterns are similar in that they all contain a Model component and a View component.
What is a Model?
This is the part of your application where all your business and validation logic is defined. It contains all the entity classes (POJOs) that are used in application and defines the relationship between them. The Model is also the component that talks to the Network Layer, Database Layer, File System etc.
What is a View?
This is where things start getting a bit shady in Android(…more on this below). For now, I am going to state simply: The view is the part of your application that displays information to your user i.e the View is the component that directly interacts with the user and is responsible for how the user is going to see our application.
But for those who are curious, the reason for the ambiguity is that in some design pattern implementations you will see that the layout.xml file has been described as the View. While in others, the Activity will be described as the View. But in reality, in Android one Activity usually manages several Views: the main screen, menu, dialogue box etc. In addition, button actions, text information and other presentation logic are usually placed in the Activity, and if the Activity is handling events can it be considered a View? I’ll leave this for you to ponder.
Differences in the three different patterns are based on what component comes after the Model and View component. We will consider each in turn.
Model – View – Controller (MVC)
In MVC, in addition to a Model and View we have a Controller. The controller holds the logic that alters the model based on actions triggered in the view. It is the component that manipulates, edits, uses the data in the Model and show it to users via the View.
Some descriptions of this pattern describe the Controller as the “middle man” between the model and view. However, you can see from the diagram that the view knows about the controller, the controller knows about the model and the view gets notified of any change in the model’s state by the model itself (therefore the model and view are aware of each other and can interact directly).
Further Reading & Comments:
The difficulty in implementing this pattern in Android is because one activity usually manages several views via fragments.It is much easier to implement this architectural pattern in iOS as the separation between the Views (UIViews set up programmatically or by visually laying out elements in Interface Builder) and the Controller (UIViewController) is a bit more clear-cut.
Model – View – Presenter (MVP)
In MVP, in addition to a Model and View we have a Presenter. The presenter acts as the middle man between the Model and the View as all communication is passed through it. The presenter listens to the events of both the view and the model and mediates the interactions between the view and model, so the model and view never communicate directly with each other. Therefore the Presenter takes the responsibility of manipulating model and also updating the view.
From the diagram, there is a one-to-one mapping between the View and the associated Presenter. The View holds a reference to the Presenter and the Presenter is reacting to events being triggered from the View. The Presenter then updates the View based on the requested actions it performs on the Model, but the View is not Model aware.
Further Reading & Comments:
Note that the MVP implementation shown above is known as “Passive View” MVP. There is another way of implementing MVP, “Supervising Controller”, where the view interacts with the model directly to bind data to the data controls without the intervention of the presenter. Links below if you would like to find out more about that.
Model – View – ViewModel (MVVM)
In MVVM, in addition to a Model and View we have a hybrid component called a “ViewModel”. The ViewModel exposes all the data and command objects that the view needs (you could think of it as a container that view goes to to get its data and actions from). In MVVM, communication between the View and ViewModel is implemented by a process known as “data-binding”. And because the 2 components are “bound” to each other, changes in the view are automatically reflected in the ViewModel and changes in the ViewModel are automatically reflected in the view. This is why develops use data-binding frameworks like Dagger2 or Google’s Databinding Library when implementing the MVVM design pattern. Also note that in MVVM, the views are regarded as “dumb” and even display logic (such as date formatting, rules to show/hide an element, and so on), should be present in the ViewModel and not the View.
You will note from the diagram that while the View holds a reference to the ViewModel by being “bound” to it, the ViewModel has no information about the View, making it possible to have a one-to-many mapping between various Views and one ViewModel. When the ViewModel alters any content/data, it notifies the binding framework that the ViewModel has changed. The framework will then automatically update any views bound to that content.Thus the View has absolutely no idea about the Model in the MVVM pattern. This is because, as far as the View knows, its “Model” is the ViewModel (hence its name) eliminating the need of the View to know anything beyond the data and actions exposed by the ViewModel. And the Model is also unaware of the ViewModels pulling data from it.
Further Reading & Comments :
The “loose coupling” of the individual components in MVVM makes them great candidates for proper unit testing. Because a ViewModel does not depend on the View anymore, with proper dependency injection you can test a ViewModel without a View even existing and vice-versa to test the Views. For example, to test a view, you could create a number of mock ViewModels that expose pre-set data (as opposed to relying on network calls or database requests), and see how that View reacts to any number of data sets relating to various scenarios.