Android MVP pattern debunked! Kotlin 💙
It has been one heck of a struggle dealing with blogs on MVP architecture that are labelled as “beginner” and use RxJava, Dagger and GOD knows what all!! It was time to write a Hello world blog that debunks the architecture for the developers who have been writing all business logic in Activity
and Fragment
and do not understand how much problem it can create.
Almost every developer out there who wanted to start with MVP has read about how the architecture works but no one is able to understand how to implement it. Well, you are at the right place! Because after reading this blog, you will be able to architect your app.
TL;DR
If you know about the key terms of MVP, then you can jump directly to implementation.
Everyone has been writing the business logic in the MainActivity
or Fragment
and this makes the code tightly coupled with the lifecycle of the app. But we can all agree to the fact not all code needs to be attached with the lifecycle. As the app grows bigger, almost 5000 ton of pain is waiting for you on the other end!!
Enter Model View Presenter. Following any architecture can make your app a less pain in the ass and can save you a ton of time maintaining and testing. MVP has a simple agenda, i.e. keep all code code away from views and as they are dumb. The aim is to separate the codebase of your app into 3 different layers that can work independently.
- View: The views are responsible for deciding how the data is to be displayed to the user. Normally the view is the
Activity
orFragment
in the app. The views does not care about what the app does when the user clicks that cute FloatingActionButton or when the user decides to logout, but what to show the user when the event occurs.
It is forbidden in the name of MVP for view to interact with model directly!
- Presenter: This is the brain of the app. All the business logic is kept here. It is responsible for keeping the view and model away from each other. View and Model can only talk through the Presenter. The view-model interaction can be:
- The view is requesting data from the model to show to the user.
- The model is updated in the background and now the view needs to be updated to show the latest information
- The view needs to update the model according to the user interaction.
Presenter prides itself to handle all of this!! 😎
- Model: This is the data centre of the app. All the data is kept here and when the model is changed, instead of updating the view directly, the presenter is notified to update the views accordingly. The data can be in form of a SQLite Database or from a network source. Usually if the app is dealing with both of them, a
Repository
is created and it acts as a wrapper around both and is responsible for synchronising with both.
You may not believe but you have been following the MVC architecture since you wrote your first click listener!!
Enough of reading, Lets dive into it!!
We are going to make a simple counter app that increments the count whenever the button is clicked. The app seems pretty simple if we had to write all the code in the MainActivity
, right? Let’s see how does it look in an architecture!! (FYI, it is hideous!! You’re gonna love it!)
So the app is divided into 4 packages, i.e. model
, view
, presenter
and contract
. You must be thinking, “Wait!! Did I miss something?? This guy didn’t tell anything about contract before!!”. Well, now is not a good time to discuss about it…
Communication
As all the layers are separated by different classes, they will communicate with each other using interfaces. For any architecture to work, firstly some rules need to be defined that all the layers will follow.
Enter Contract. We create an contract interface in which all the interfaces are defined that will be implemented later on.
In the above gist, the View
, Presenter
and Model
interfaces are defined which contain the methods that will be called.
The View
Interface contains the methods initView()
and updateViewData()
as this interface will be implemented by the view and the initView()
method will create the initial view. The updateViewData()
method, will be called when the model updates and the view needs to be updated.
The Presenter
Interface contains the methods, incrementValue()
that will be called when the model needs to be updated and the getCounter()
method that need to be called when the view needs to access the data from the model.
The Model
Interface contains the getCounter()
method that will return the value stored in the model and the incrementCounter()
method that will increment the value in the model.
The most important part of architecture is to design the contract as it will define the communication between your layers.
View
Lets have a look at the view layer of the architecture. As discusses before, the Activity
or the Fragment
will be in the view.
The view will implement the View
interface. The view only needs to know about the presenter so an instance of MainActivityPresenter
. In the onCreate()
of the MainActivity
, the presenter is instantiated.
Presenter
Now is the time of the presenter layer of the architecture. The presenter acts as an intermediate for the view and the model. So, the presenter needs to know about both, the view and the model.
As the presenter is instantiated from the View, every presenter should be attached to a view that it will interact with. So, an instance of the view interface is passed into the constructor. When the presenter is instantiated, an instance of the model is also created.
After all the layers have been created the view needs to be populated. So the initView()
method is called from the view object.
Things maybe start making sense now, that as the presenter knows about both the layers, it can control both of them.
Model
The final part is here!! 🎉
The model contains only the data and as in our sample app the data is just a variable that is updated each time the button is clicked. So will keep a member variable and implement the Model
interface whose callback methods will be called when the data is to be accessed or updated.
This class overrides the getCounter()
method that will be called when the data is need from the model and the incrementCounter()
that increments the value. By now, you might have guessed that these methods will be called from the presenter and not the view.
That is it! Congratulations!!🎉 You have successfully completed your first MVP app!!!
I hope this blog helped you understand how to implement an architecture pattern in your app. The working code is uploaded on GitHub.
I would recommend you to try and make a simple app on your own so that you have some hands on practice on how things work. Just reading many blogs won’t be of any help.
Share and Clap 👏 if this blog helped you! Any suggestions would be appreciated!
Keep practicing and happy coding!!