MVP [Model — View — Presenter] in Android

Chirag Chavda
IndiaNIC
Published in
5 min readMar 1, 2017

MVP is one of the software development design pattern which is currently in use by many android application developers for better app development. I am developing android apps since release of Android Jelly bean 4.2.2. At that time, it had very few functionalities. As time passed, it grew like dinosaur and things became more complex. Developers were using MVC pattern on which android works by default. In that, Model consist JSON/XML, View consist JAVA/XML and Controller consist Activity. Mostly people work with View and Model in MVC pattern which makes it complicated and messy. To rescue developers from that situation MVP helps to simplify the solution.

What is MVP ?

The MVP pattern allows separate the presentation layer from the logic, so that everything about how the interface works is separated from how we represent it on screen.

  • Model : The Model holds the business logic of the application. It controls how data is created, stored, and modified.
  • View : The View is a passive interface that displays data and routes user actions to the Presenter.
  • Presenter : The Presenter acts as the middleman. It retrieves data from the Model and shows it in the View. It also processes user actions forwarded by the View.
Layers in MVP

Why MVP ?

  • In Android we have a problem arising from the fact that Android activities are closely coupled to both interface and data access mechanisms so all logic of view and model remains in activity which generate complexity.
  • For an application to be easily extensible and maintainable we need to define well separated layers.
  • MVP makes views independent from our data source. We divide the application into at least three different layers, which let us Test them independently.

How to implement MVP ?

  • Up to now there is no “standard” way to implement it .
  • There are many variations of MVP and everyone can adjust the pattern idea to ​​their needs and the way they feel more comfortable.
  • For ex, Is the view responsible to enable or disable a progress bar, or should it be done by the presenter ?

Let’s see by using an example. I will make a login module in this example. First we will make interfaces for View, Presenter and Model of Login Module.

Interface for Login Module

Above interfaces will use to pass data between three layers. To implement this interfaces we will create three classes which will implement the defined methods of interfaces.

View

Above methods will interact with view layer to update user interface as needed. This ILoginView will be implemented by LoginActivity.

public class LoginActivity
extends AppCompatActivity implements ILoginView {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
}

@Override
public void showLoading() {
}

@Override
public void hideLoading() {
}

...
}

Presenter

People have different approach for presenter. Some people will execute Async in presenter itself and some prefer to just call method of model (interactor). I personally prefer calling only model methods and do all Async and Logical programming in Model (Interactor) implementation class. So we will use presenter (Middle Man) as passing data and events to view-model and visa versa.

public class LoginPresenterImpl implements ILoginPresenter {


ILoginView mILoginView;
ILoginInteractor mILoginInteractor;

public LoginPresenterImpl(ILoginView loginView, ILoginInteractor loginInteractor) {
this.mILoginView = loginView;
this.mILoginInteractor = loginInteractor;
}


@Override
public void callLogin(String username, String password) {
mILoginView.showLoading();
mILoginInteractor.login( ... );
}
}

In LoginPresenterImpl, we will have instance of view(ILoginView) and Model(ILoginInteractor) which call methods as needed.

public class LoginActivity
extends AppCompatActivity implements ILoginView {
private LoginPresenterImpl mPresenter;@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);

// Initialize presenter here
mPresenter = new LoginPresenterImpl(this, new LoginInteractorImpl());
}

We will initialize presenter in onCreate of Activity. Then pass view into constructor using this and create new Interactor (Model) instance.

Model

Here login method will have all business logic of authenticating user to application. I have created other two inner interfaces IOnLoginFinishedListener and IValidationErrorListener to return data/result back to presenter.

isDataValid method will have data validation code. If any error found in data then validationErrorListener will pass error to presenter and then presenter will change view according to error. If username and password is correct then login method will authenticate user. If authentication gets successful then getUserData method will return user information else errorMsg method will return error message to presenter.

Now you can see that LoginInteractorImpl class contains pure java code with core business logic only. There is no single android component or context exist in it, which makes it easy for testing. Also, the code becomes more simpler to understand.

Click Here to get source code.

Automated Testing

Building your application in 3 different layers helps you to test each layer in isolation. Testing can be automated to a large extent.

Testing is mainly divided into 2 parts

  1. Unit Testing: used for testing the Presentation and Data Layers
  2. Instrumentation Testing: used for testing the View Layer

Unit testing for the Presentation Layer and the Data Layer can be done on the JVM using JUnit4.

Instrumentation tests are done for the View Layer, which requires an Android device. We can use Espresso to write instrumentation tests.

You might be wondering about how we test each layer in isolation without requiring input from the other two layers. For that, we use Mockito to make mock objects in Java.

Pros & Cons

Pros

  • Leads to TDD (Test Driven Development)
  • Can achieve information hiding
  • Code Reusability and Maintainability
  • Easy to review code

Cons

  • Extra learning curve
  • Requires time before starting coding
  • Increase redundancy in code if your app size is small

Conclusion

There is no silver bullet, MVP itself is just one of the solutions (MVC/MVVM/MVP). Even it can be mixed with other methodology as well. We also need to take in consideration that small project development with MVP will not be productive. So we need to choose patterns selectively for different projects.

checkout the example source code from here

--

--