Refactoring our code — The MVP design pattern for Android
Having worked as an Android developer for a few years now, the lack of an established design pattern when building an app is easily noticeable. At the very beginning of Wolox, we started accounting for what all our designs had in common across our developers. From this we began developing a small framework with no name or particular designation, just a bunch of small components (custom fragments, activities, adapters, etc) that we had built and could use across most apps to make our lives easier, which ultimately is what every team looks forward to!
This pool of components soon started to grow bigger and, as apps grew bigger too, we started noticing the need of something a little bit more structured, an actual pattern that could glue all our components together to give it sense and structure. That’s why we gave MVP a try and adapted the idea from this lecture into a practical and more suitable solution.
See also: Customizing Components-Radio Button
The Model-View-Presenter pattern
Besides MVP meaning “Most valuable player” in many sports circuits I’m going to attempt to focus today on a more technology-related meaning of it, Model-View-Presenter.
First of all let’s quickly state the problem we’re trying to solve with this pattern and how it reflects when building an Android app.
Android code is mainly contained within Activities and Fragments each of which has a different purpose but they both handle most of the business logic. They interact with the view and make the asynchronous calls when necessary, they know the model, they know how it is represented on screen and how to perform a request to an outside service for information. They definitely know too much (and do too much).
This basically results in classes flooded with code that goes everywhere, from the view to the data layer and for big apps it can easily become pretty confusing. Perhaps sometimes the use of a service class can make things simpler but doesn’t quite hit the mark for the simplicity we are trying to achieve.
Here is where the Presenter concept comes in and provides an abstraction layer that could solve every single problem in our lives, or probably just give our code some structure and make it way more readable. This layer is in charge of handling the business logic and providing the already processed data to the views (Fragments and Activities) which will then display it in any format that they want without the need of knowing where it comes from or how it was processed. Also asynchronism is taken away from the views which adds a lot of semantics to them becoming just a media to display information.
A last huge advantage of this is that the view and the presenter can be tested separately and the presenter itself can be tested using unit tests; then again, making our life just simpler and happier.
Now, let’s go into detail on how this works and where the responsibilities for each layer begin and end.
So what’s the main idea?
Model: This is the well known model, present in many of the most common patterns and use cases. It represents the world we are working with, every real world element that our app should know how to represent. Both the View and the Presenter are aware of this model and they know how to use its properties and methods (the view doesn’t really need to know the model and originally shouldn’t but it’s a tradeoff that avoids the need to have setter methods for every field that we want to update) .
View: As stated before, views are our Fragment and Activity classes that we are using, they are able to alter the UI as we need and they need to receive structured data from a source in order to populate themselves. This layer shouldn’t know anything else about the obtention of the data, we made it as simple as we could.
Presenter: This layer, introduced here, is implemented with native java code meaning it doesn’t need to know whether it’s used in an Android application or a web service. How does this work with our structure previously described? Easy, what we are going to add to each view is a simple interface which defines the actions that any view using a specific presenter would need to do in order to populate itself with the data it provides.
Finally, in order to implement this new design pattern we decided to use a few custom classes from which we extend every View and Presenter that we want to build.
BasePresenter — The class for every presenter to extend from
WoloxFragment — Has a related presenter that it interacts with.
See also: Customizing Components-Range Input
Now with these classes in mind, we can provide a small example of how this is used. Let’s take a very simple use case such as loading user information and populate a Fragment whenever the information asynchronically arrives from the data source.
First we need to create a simple view to glue both presenter and fragment together containing the methods they will use to interact with each other.
Just as a small note, LEView is a custom interface that contains the methods showErrror() and showLoading() which we commonly use across our views. Now let’s take a look of how the fragment showing the user information would look like.
We can note that all the logic it contains refers to how to display elements in the view and the methods all look synchronous. So all the magic has to happen in the presenter, then let’s look at it’s implementation to close this cycle of code. We made this example using Retrofit to obtain the data from an API.
So this is pretty much it, initially it may seem like a little bit of an overhead to create this 3 classes for each View but after a while your code starts being amazingly more maintainable, testable and clean. Personally, I would recommend to, at least, give it a try and if you happen to like it, just tell your friends and family to always use MVP when developing Android applications!
Thanks for reading!
Posted by Lucas Moscovicz (lucas.moscovicz@wolox.com.ar)