Android Architecture MVC, MVP and MVVM Design Patterns – A Detail Tour
- September 25, 2019
- Adnan Sattar
There are many different architectural approaches available these days like MVP, FLUX, MVI, MVVM etc. One can use any approach as long as code is maintainable. MVC, MVP, and MVVM are three popular design patterns in software development. All these design patterns by and large help in developing applications that are loosely combined, easy to test and maintain. All discussion about the pattern is made in context of Android as a platform.
As developer community has mostly abandoned the conventional Model View Controller (MVC) pattern, what alternatives have been adopted? We take a look at Android architecture types of today and hit the most popular one’s head-to-head in MVP vs MVVM comparison.
Android itself is written as MVC where Activity is responsible for more or less everything.
MVP is mature, amazing yet Google introduced Android Architecture Components which included ViewModel rather than Presenter and hence the proof that even Google is supporting MVVM.
Use in situations where the connection between the view and the rest of the program is not always available and effectiveness of MVVM or MVP not works. This clearly describes the situation where a web API is separated from the data sent to the client browsers. MVC design pattern divides an application into three major aspects: Model, View, and Controller.
Model means data that is required to display in the view. Model represents a collection of classes that describes the business logic (business model and the data model). It also defines the business rules for data means as how the data can be changed and manipulated.
The View represents UI components like XML, HTML etc. View displays the data that is received from the controller as the outcome. In MVC pattern View monitors the model for any state change and displays updated model. Model and View interact with each other using the Observer pattern.
The Controller is responsible to process incoming requests. It processes the user’s data through the Model and passing back the results to View. It normally acts as a mediator between the View and the Model.
Use in situations where binding via a datacontext is not possible. In order to separate the view from the model, a presenter is needed. Since the view cannot directly bind to the presenter, information must be passed to the view via an interface.
The MVP pattern is similar to the MVC pattern. It is derived from MVC pattern, wherein the controller is replaced by the presenter. This pattern divides an application into three major aspects: Model, View, and Presenter.
MVP DESIGN PATTERN
The Model represents a set of classes that describes the business logic and data. It also defines business rules for data means how the data can be changed and manipulated. It is responsible for managing the data. It maps the data received from the data source (Database or Network call) through the Repository/Service to domain objects.
It is solely responsible for presenting the data to the user. It can be implemented using Activities, Fragments, etc. The view is as dumb as it possible and every logic is handled by the presenter. This is because it is very hard to test the view because of the framework complexity and in order to write as many tests as possible, the view is kept very dumb.
View is a component which is directly interacts with user like XML, Activity, fragments. It does not contain any logic implemented.
The view is responsible for handling for example:
- Event listeners
- Showing dialogs, Toasts, Snackbars
- Working with Android View and Widget
- Starting activities
- All functionality which is related to the Android Context
The presenter contains the business logic. It is responsible for getting the data from Repository/Service and updating the view based on the data received. It also handles the user interactions with the view.
The Presenter receives the input from users via View, then process the user’s data with the help of Model and passing the results back to the View. Presenter communicates with view through interface. Interface is defined in presenter class, to which it passes the required data. Activity/fragment or any other view component implement this interface and renders the data in a way they want.
In the MVP design pattern, the presenter manipulates the model and also updates the view. In MVP View and Presenter are completely decoupled from each other’s and communicate to each other’s by an interface. Because if decoupling mocking of the view is easier and unit testing of applications that leverage the MVP design pattern over the MVC design pattern are much easier.
Use in situations where binding via a datacontext is possible. The various View interfaces for each view are removed which means less code to maintain.
MVVM pattern supports two-way data binding between View and View-Model. This allows automatic propagation of changes, inside the state of View-Model to the View. Generally, the View-Model utilizes the observer pattern to inform changes in the View-Model to the Model.
MVVM DESIGN PATTERN
The bi-directional data binding or the two-way data binding between the view and the View-Model ensures that the models and properties in the View-Model is in sync with the view. The MVVM design pattern is well suited in applications that need support for bi-directional data binding. View has a reference to View-Model but View-Model has no information about the View. There is many-to-one relationship between View and View-Model means many Views can be mapped to one View-Model. It is completely independent of Views.
The view model has the following responsibilities:
- Exposing data
- Exposing state (progress, offline, empty, error, etc)
- Handling visibility
- Input validation
- Executing calls to the model
- Executing methods in the view
The Model comprises data, tools for data processing, business logic. Kind of the brain of an app. It is not tied to the View, reusable in many contexts. Contains a data provider and the code to fetch and update the data. The data can be retrieved from different sources, for example:
- REST API
- Realm db
- SQLite db
- Handles broadcast
- Shared Preferences
The View ties to variables and actions in a flexible way, and is responsible for data visualization. It transmits values into ViewModel, thus changing the UI view.
let’s see what are some of the drawbacks to MVVM pattern:
- Some parts of the code end up in XML, thus complicating either debugging or development;
- In Android environment you are forced to work with the View in two ways: using DataBinding and/or View methods;
- Writing tests for an application won’t be a light task.
At the same time, there are certain strong advantages:
- Using the official Google library that assures a proper generation of components;
- Review at compilation stage;
- No need for dozens of findViewById, setOnClickListener or similar code;
- Possibility to write custom xml-attributes with the help of Binding adapters.
For each Activity/Fragment (View) we require a Presenter. This is a hard-bound rule. Presenter holds the reference to the Activity and Activity Holds the reference to presenter. 1:1 relationship and that’s where the biggest issue lies.
As the complexity of view increases, so does the maintenance and handling of this relationship.
This eventually led to same issue we faced earlier as in for quick changes in design, we actually need to modify the whole relationship.
Picking a statement from our end goal “Build things in a distributed manner”, In order to achieve it and to avoid this tight relationship ViewModels were introduced.
ViewModels are simple classes that interacts with the logic/model layer and just exposes states/data and actually has no idea by whom or how that data will be consumed. Only View (Activity) holds the reference to ViewModel and not vice versa, this solves our tight coupling issue. A single view can hold reference to multiple ViewModels.
Since Presenters are hard bound to Views, writing unit test becomes slightly difficult as there is a dependency of a View.
ViewModels are even more Unit Test friendly as they just expose the state and hence can be independently tested without requiring the need for testing how data will be consumed, in short there is no dependency of the View.
The key difference between the Model View Presenter model and the Model View ViewModel lies in the way they update the view. The MVVM uses databinding to update the view whereas the presenter uses traditional methods to update the view.
- Consists of Model, View, and Presenter layers;
- View delegates user input to Presenter; both of layers should have a 1 to 1 relation;
- View and Model aren’t tightly coupled for clear separation of concerns;
- View connects to the Model via data binding directly;
- Easy unit testing, as an interface for Presenter layer one may mock quickly;
- Includes three key parts: Model(business rule, data access, classes), View (user interface), ViewModel (as agent between view and model);
- Great solution to handle tasks related to Windows Presentation Foundation system (WPF) and Silverlight application framework;
- Provides clearer separation of the UI and application logic;
- Unit testing even easier, as there is no dependency on the View;