DEV Community

Héctor de Isidro
Héctor de Isidro

Posted on • Edited on

3 2

Presenters and Views meet The Interface Segregation Principle

also known as “the 4th letter in the SOLID acronym”

Superman vs. Muhammad Ali Comic Book

There are several posts about the MVP¹ pattern (or whatever fancy name some authors use to call it :wink:) and even more of them explaining what SOLID² stands for, so we will focus on:

  1. The contract between presenter and view
  2. Code reuse

Speaking of MVP and contracts, some developers should read this for goodness sake!

DRY³

Time and again we are told that we must avoid repetition and redundancy because “the less code to maintain the better” but then we find ourselves typing almost the same interfaces over and over again an indefinite number of times.

class MainPresenter : BasePresenter<MainPresenter.Contract> {
...
interface Contract : BaseView {
fun update(list: List<Item>)
fun showProgress()
fun hideProgress()
fun finish()
...
}
}
class DetailPresenter : BasePresenter<DetailPresenter.Contract> {
...
interface Contract : BaseView {
fun update(item: Item)
fun showProgress()
fun hideProgress()
fun finish()
}
}
... and so on
view raw mvp-isp-dry.kt hosted with ❤ by GitHub

It’s almost pseudo-code, but I’m sure it’s not the first time you’ve seen something like that :shrug:

KISS⁴

What can we do to follow the DRY principle mentioned above? Applying the Interface Segregation Principle. That’s it.

interface ViewContractUpdateList<in TYPE> {
fun update(list: List<TYPE>)
}
interface ViewContractProgress {
fun showProgress()
fun hideProgress()
}
interface ViewContractFinish {
fun finish()
}
...
class MainPresenter : BasePresenter<MainPresenter.Contract> {
...
interface Contract : BaseView,
ViewContractUpdateList<Item>,
ViewContractProgress,
ViewContractFinish {
...
}
}
view raw mvp-isp-kiss.kt hosted with ❤ by GitHub

What do you think? From my point of view, among other benefits, it looks much cleaner, more refactor-friendly and certainly a better way to avoid monolithic interfaces with hundreds of methods.

BONUS: Kotlin developers

Kotlin offers Sealed classes whose best description is: Enums with super-powers. Using this kind of class we may be able to go a little further.

sealed class State {
object Empty : State()
object Progress : State()
class Content(val list: List<Item>) : State()
class Error(val message: String) : State()
}
interface ViewContractState<in TYPE> {
fun state(newState: TYPE)
}
class MainPresenter : BasePresenter<MainPresenter.Contract> {
...
interface Contract : BaseView,
ViewContractState<State>,
ViewContractFinish {
...
}
}

Further information about these Sealed Classes is available here :trophy:

Conclusion

It’s true that we haven’t gone into the details but I think the code fragments shown above are worth more than a thousand words :sunglasses:

We here at Lolamarket believe that our code looks way better using this so I encourage everyone to try it and leave a comment below or tweet me with any questions/suggestions!

This article was originally published on Medium


[1] Model-View-Presenter (btw it’s impressive to know this architectural pattern is over 20 years old :wow:)
[2] SOLID (the acronym is not used in its original paper so look for the reference to “the first five principles of class design” or even better go for a easier explanation)
[3] Don’t Repeat Yourself
[4] Keep It Short and Simple (politically correct variation)


External links 👀

Sentry mobile image

Is your mobile app slow? Improve performance with these key strategies.

Improve performance with key strategies like TTID/TTFD & app start analysis.

Read the blog post

Top comments (0)

Sentry mobile image

Mobile Vitals: A first step to Faster Apps

Slow startup times, UI hangs, and frozen frames frustrate users—but they’re also fixable. Mobile Vitals help you measure and understand these performance issues so you can optimize your app’s speed and responsiveness. Learn how to use them to reduce friction and improve user experience.

Read the guide →

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay