Death of MVP
MVP, Model View Presenter, has been a staple of the android community since square heavily promoted it back in 2014.
Although I didn’t know it at the time, Android MVP died on May 17th, 2017. That’s Google I/O. The day that android architectural components were released.
MVVM is now the clear choice for making Android applications. Before we bury MVP, explain how MVP died, and why to embrace MVVM, let’s give it a short eulogy.
The foundation: Clean Code
There are more articles about clean code than any one person would care to go though. I’m not going to hash everything out but there are some things that are worth repeating:
Clean architecture aims at making as much of the business logic testable while looking at everything else as a plugin. This architecture works by implying The Dependency Rule, which states that the source code dependencies can only point inward. Nothing in an inner circle can know anything at all about something in an outer circle. Enforcing this rule means that crossing boundaries should be done by passing simple data structure between the two and using interface relationships such that source code dependencies oppose the flow of control.
In our continuous effort to achieve the best architecture we must kill off MVP.
Who is MVP and what does he Do?
Just like clean code, there are many articles about MVP. It’s not worth going into detail here, but there are a few things worth mentioning.
MVP separates the presentation layer from the logic so that everything about how the interface works is separated from how it is represented on the screen. The three parts are model, view, and presenter. The model defines the data to be displayed. The view is a passive interface that displays the data and routes commands to the presenter. The presenter acts upon the model and the view. It is responsible for retrieving data from the business logic and formatting it for display in the view.
MVP clearly fits the clean architecture mantra. With the detail diagram above you can see that the flow back from an asynchronous call is done via an interface. Great for testing and awesome for modularization! The takeaway, however, MVP likes everything to be an interface. Here, a presenter and interactor share flow but in different planes. Presenter is platform specific, and interactor is platform agnostic.
I got 99 problems but MVVM ain’t one.
Model-View-ViewModel is another way to achieve clean code. There are many articles written about this topic but here are a few take aways for our discussion.
In MVVM, we invert the dependency arrow between the `View` and `Presenter`, and rename the `Presenter` to `ViewModel`. This newly renamed `ViewModel` does not “act” upon a `View` as a `Presenter` would, but instead provides the `View` with an interface it can bind to in order to observe changes and propagate user actions and updates to the rest of the system.
MVVM clearly fits the clean architecture mantra. With the detail diagram above notice that callbacks via an interface are not present. Instead the mantra is to bind. Views bind to asynchronous data events. The ViewModel is a concrete class and is the brains of the operation. The take away, MVVM likes to bind to events and use concrete classes.
The final blows
There were three major blows to MVP:
Android Data Binding — Bind with purpose
Android data binding generates a binding class for a specific layout. This class holds all the bindings from the layout properties. Instead of findViewById(), we get everything via one data binding object. However, the real power of data binding is allowing your view objects to get notified when data changes. You can achieve this via observable objects, observable fields, and observable collections.
Android Data Binding…Data Binding…Binding. Which architecture uses this terminology? Obviously binding is a key part of MVVM. In order maximize usage of this tool you need to setup your binding and observables. MVVM clearly accomplishes this with the ViewModel. There you put observable objects to where the view can bind.
With MVP you can’t easily bind. Your ViewModel in MVP is just an interface. Your Presenter is just an interface. Let’s not go there. MVP developers, if they decide to use binding, would mostly use it to assign values directly. In most cases, they remained true to butterknife and didn’t bother with data binding.
Clear winner, MVVM.
ReactiveX — Once I was blind, but now I see.
Functional reactive programming is a mouthful. Making the assumption you understand observables, observers, and subscribers, let’s see how Rx holds up for each architectural pattern.
With MVVM it’s clear where you subscribe to data. You bind or subscribe to asynchronous events in the ViewModel. MVVM terminology supports it. Views bind or subscribe to events off the ViewModel via Subjects. Awesome, but is it enough to kill MVP?
MVP can get confusing where to subscribe or bind. Presenter? View Controller? Most MVP developers positioned the asynchronous calls and subscriptions in the presenter. Then, via the ViewModel interface, call into the view controller directly.
On it’s own, Rx is not enough to kill off MVP, but let’s combine it with Android Data Binding. Now here we clearly have a winner. MVP awkwardly fits these two pieces together into one flow or ignores data binding all together. You don’t put a square peg into a round hole.
Clear winner, MVVM.
Android Architectural Components -A decade in the making
As a developer for iOS and Android (Yes, I really do both) Android was the more difficult to learn when it came to view controller management. In iOS you never lost the view controller during a rotation. You never lost the view controller for simple reasons like launching the camera. Seriously! In iOS, you are warned when memory is low. In iOS, if your application is removed from memory, you don’t relaunch out of sequence.
Android took a different approach. Android created headaches. In order to work on low end devices they constantly save state. It was built into the lifecycle. This made it difficult for Android developers to make apps for both portrait and landscape. Added to that, the application restore responsibility kept launching you out of sequence.
In most cases, we said ‘screw it’…until now.
Finally Android has a component that clearly lasts through rotation. We are still required to save state during a restore, but it is a lot easier when saving happens less often. It’s now ok to take advantage of asking the user to wait while you reload.
So where does Android ViewModel belong? MVVM clearly has a ViewModel component from which you can use to extend. What about MVP? ViewModel is just an interface. It’s just a pass through from presenter to controller. What about using the presenter? You could technically do that, but do you really want to? Do you really want to fit that square peg through the round hole?
Clear Winner, MVVM!
Rest in peace MVP
MVP served the android community well. We say goodbye with much appreciation. It helped increase our culture for reliable code, it expanded our modularization, and it even helped hone our craft.
And now, his watch is ended.
Feel freet to follow me on Twitter, and The Medium.