Stefan Nägele
30. January 2018
4 min

MVP without Contracts

In this post, I want to show you how we implemented the MVP (Model View Presenter Pattern) without using a contract to improve our development speed. Before I gonna start, I have to speak verbosely when and why we started to implement the MVP and why we made the decision to not implement the typical MVP contract abstraction layer. The app and thereby the code examples are completely written in Kotlin, so if you are not (yet) familiar with Kotlin, you can check out the Android developer docs: https://developer.android.com/kotlin/resources.html

Now let’s start!

SprIT – a legacy

A couple of months ago, we reimplemented and re-released our free gas station app SprIT for Android. There were urgent reasons why we decided to reimplement the app from scratch. The app was initially developed in 2013 and therefore the code was born in the old Jelly Bean and KitKat days.

Dealing with async tasks, no Marshmallow permission management, no separation of view, presenter and business logic, no Material Design etc.

For sure it is impossible to use and adapt every new cool library, framework or pattern but the code was light years behind modern Android development.

Introducing an architectural pattern

One of our first actions was to apply an architectural pattern in our app. We decided to implement the most common used pattern for Android *drumroll* The Model View Presenter Pattern (MVP) .

The contract

MVP Android implementations are well-known to define additional interfaces for views and presenters as contracts. The presenter only receives the interface to decouple the presenter from the actual given view, et vice versa.

It all starts with the abstraction layer:

Three abstraction files later, the actual implementation of a SettingsView and its presenter can actually start:

No groundbreaking enlightenment in 2018, it’s just the usual way how to implement MVP.

MVP – No contract!

We resigned to create the contract abstraction layer. Why? In our case every presenter corresponds to one specific view. Specifying an additional interface results in redundant code.

Don’t get us wrong: When a presenter is required by several views or a view requires different presenter implementations, the contract is totally justified. But defining an interface for a single implementation? There are pros and cons to design interfaces for that.

Pros:

  • Helps to design the communication in a cleaner way
  • Living documentation what the view and the presenter actually do between each other

Cons:

  • More boilerplate code
  • More maintenance overhead in case a contract changes

Our opinion

In our humble opinion, the implementation of the interaction between view and presenter and its unit tests are a already a living sufficient documentation. Designing an interface is of good assistance for defining the communication but in our particular case for a small app and a small developer team it is additional overhead we personally did not need.

Implementation

Below the final implementation without any contracts. To attach and detach presenters, we are using RxLifecycle to make this step more convenient and reactive.

Testing without contracts

By omitting contracts, we have to verify Android SDK calls directly (we are using the Mockito-Kotlin library by Niek Haarman https://github.com/nhaarman/mockito-kotlin btw).

Indeed, there is no abstraction and it can result in additional mocking for Android classes and thereby code we do not own. On the other hand, we can already technically verify that we are invoking the right (mocked) Android calls in unit tests and don’t have to wait for UI tests to get the first feedback for that. We think that there is a benefit to check that we trigger the right Android calls with the right values at the right time by the presenter in our presenter logic.

Conclusion

Omitting the Android MVP contract approach is a radical design decision we’ve made so far compared to the other tutorials and best practices guidelines out there.

Because every presenter maps one view, we think it boosts our development speed by reducing boilerplate code instead of defining interfaces.

Dear community, what do you think of MVP without contracts? Maybe you have some cool reasons why or when it should still be recommended using contracts!

Stefan

Comment article