I know, I know… I used a buzzword in the title. Lately everybody is talking about MVP, especially for Android. I will try to explain the whole buzz around MVP — why it is a great architectural pattern, and most importantly how to understand it.

I will do this in a series of posts. I will start with the theory (part 1); continue with a practical example, a simple Android app (part 2); show you how easily you can write tests for your UI (part 3); and finish with swapping the Android UI with a simple Java console “UI” (part 4).

The theory

MVP (Model — View — Presenter) is just another fish in the big sea of architectural patterns. Its goal is to establish a clean architecture by separating different concerns. Uncle Bob wrote a great article about that, which is a must-read before continuing on with my article.

As you [now] already know, the most important thing in the clean architecture philosophy is that you have only a one-way communication between your layers. The inner layers are NOT aware of the outer layers. Never! No exceptions! No shortcuts!

Separating your code into layers

The hardest part is this — separating your code into decoupled layers. So, how do you know which component goes to which layer? According to a rule of thumb, you separate your code into the following layers:

Model — in this layer you have all the data classes. Usually these are the classes in which your ORM maps the data from the database and their DAO classes; or the classes in which you [de]serialise your data from some REST interface.

— in this layer you have all the data classes. Usually these are the classes in which your ORM maps the data from the database and their DAO classes; or the classes in which you [de]serialise your data from some REST interface. App logic — here you have all the classes that contain the actual application/business logic. Usually these classes do the heavy lifting and glue all the classes together from the model layer. In the MVP pattern, this layer doesn’t exist. I just want to do a separate layer because it adds flexibility to the code.

— here you have all the classes that contain the actual application/business logic. Usually these classes do the heavy lifting and glue all the classes together from the model layer. Presenter — here you have the presenter interfaces and their implementations. The presenter classes are responsible for reacting to view events (user input), processing that data only by delegating that to the app logic layer, formatting the results returned from the app logic layer and passing the results to the view.

— here you have the presenter interfaces and their implementations. The presenter classes are responsible for reacting to view events (user input), processing that data by delegating that to the app logic layer, formatting the results returned from the app logic layer and passing the results to the view. View — here you have the actual views. Usually on Android these are all the Activity and Fragment classes.

The connection between the layers is the following (from the outermost layer to the innermost layer): View → [Presenter → App logic] → Model. Again — the communication is unidirectional.

The Model knows nothing about the other layers.

knows nothing about the other layers. The App logic knows only about the Model layer.

knows only about the layer. The Presenter knows only about the App logic and the Model layers, but communicates directly only with the App logic layer.

knows only about the and the layers, but communicates directly only with the layer. The View is aware that all the other layers exist, but communicates directly only with the Presenter layer.

But we need bidirectional communication

We certainly do. The most obvious example is the communication between the View and the Presenter layers. When the View reacts to an UI event (e.g. click on a button) it informs the Presenter of the event. After that the Presenter does it’s job (it calls a corresponding class of the App logic layer). There is a great chance that the Presenter will do it’s job in a separate thread and not on the main UI thread. Actually, that is a must in every Android app. So, how do we “communicate” back the results from the Presenter layer to the View, without breaking our unidirectional communication rule?

Again, as you should already know, because you read this in Uncle Bob’s article, we do this by using the Dependency Inversion Principle. How does this look in code? Very simple. For every Presenter interface, you define another interface that represents the communicator. For example, for the LoginPresenter:

interface LoginPresenter { /**

* We communicate with the View through this interface

*/

var viewCommunicator: LoginViewCommunicator?



/**

* Does the actual login

*/

fun login()

}

we define the following communicator:

interface LoginViewCommunicator {



/**

* Called on successful login

*/

fun loginSuccessful()



/**

* Called when the login is unsuccessful

*/

fun loginFailed()

}

So, when the View calls the login() method of the Presenter, the Presenter will deliver the results by calling the appropriate method (loginSuccessfull() or loginFailed()) of the LoginViewCommunicator interface.

But you may ask yourself: Doesn’t this break our unidirectional rule? No, because the communicator interface is part of the Presenter layer and the Presenter calls the method from it’s own layer (and not the View layer).

This pattern helps us keep the unidirectional rule and the Presenter layer completely independent from the View layer.

Why is this layering important?

There are two main reasons why we layer the code:

We get a clean and flexible code base. This gives us the option to switch any part of the code without much hassle. The code is testable. We get to write reliable tests without any pain. Even UI tests.

So, that’s enough theory. In the next part of this series, I will show you a practical example, by writing a simple Android app that’s based on the MVP pattern.