- THE MUST HAVE ANDROID DESIGN PATTERN -

To create a neat, nice loosely coupled design, that scales well in large projects, isn't that the dream? Coming up with a pattern that has withstood the test of time, and that is easy to understand? Why is it so nice to have something like that on paper, but having something like that is practise is often much harder? As it turns out, it all has to do with craftsmanship. Knowing when to use which design pattern is key, because there is no such thing as a silver bullet... or is there?

No, there is not, but Model View Presenter comes close. As far as design patterns go, you can almost always rely on this one while crafting Android apps. This pattern is almost always the one you want to be using, when dealing with Activities or Fragments. At its core it just splits the responsibilities that Activities and Fragments have, which are:

  • Managing the lifecycle
  • Dealing with the user
  • Juggling logic around
  • Doing some actual work

These responsibilities are quite fierce, and for all sorts of reasons it is important not to mix these. Quite often I've seen Fragments existing out of 500+ lines of code, that mix UI elements with business logic, and their behaviour heavily relies on the state of the Fragment lifecycle. Good luck finding the bugs that are surfacing in the field. Usually these classes start neat and maintainable, but within a couple of sprints they are bloated with new functionality that totally obscures how things work.

How cool would it be to have a lightweight template that will make sure you have everything setup to make your code:

  • Focussed - Small classes doing just their job.
  • Readable - Easy to understand what the goal is, and how it is realized.
  • Maintainable - Simple to add and rework stuff.
  • Reuseable - Loosely coupled, so you can compose the system.
  • Testable - No weird dependencies, so plug in your production or test behaviour.
  • The works - There's more awesomeness, just keep on reading...

At the cost of minimal ceremony Model View Presenter will do that for you. It introduces 3 concepts in every Fragment, each with their own responsibility.

The Most Valuable Pattern

Nobody likes unnecessary ceremony, and luckily there is no need for it. On my Github you can find a Kotlin Skeleton project that contain the basics you need to get a nice template. Feel free to use it, or not. I recommend reusing at least the mvp package. Further down I'll explain what that code does, but first let me explain how the pattern does it's job.

Managing the lifecycle

Since Android loves it's share of inheritance this job will be the job of the Fragment. The Fragment has to handle the - sometimes complex - lifecycle that the folks at Google have devised. It will be translating the lifecycle into the instantiation of the View and Presenter.

Dealing with the user

The FragmentView is responsible to deal with the user. The user can do some complex things, and we need to account for that. This class will handle all the TextViews, EditTexts, RecyclerViews, Buttons and whatnot.

Juggling logic around

It's all nice to work with the lifecycle and user, but the eventually we need to exercise the business logic. That's where the FragmentPresenter comes in. It is the middleman between the View and the Model, where Model is just a fancy word for the business logic. Ideally the Presenter shouldn't do complex operations, it should utilize different classes from the Model to get some useful data or operations, and then pre-process them for the View. And the other way around as well, when the view exercises the Presenter, it needs to utilize the Model on behalf of the View.

Doing some actual work

Finally we need to do some actual work. Several classes throughout the system are responsible for things like querying the database, connecting to a backend, or do complex algorithmic on data. As said just before, the Presenter shouldn't be doing these kind of things, it should know how to compose several objects from the Model that do this. A typical name for such an object is Interactor, this name is not enforced however. Like the Model, an Interactor is a concept.

The View and Model should never work directly with each other. The Presenter is responsible for connecting both and hooking up the business logic.

Model View Presenter Fragment overview of responsibilities

Technically the Interactors and Fragment are part of the Model, however the Fragment has a special role other then all the other objects in the Model. The Fragment's responsibility hooks into the OS, Android that is. Therefore it is not responsible for typical backend stuff, database things or fancy logic, but for creating things. It's job is to create the dependencies, to create the View and Presenter with the necessary Interacors, and connect the OS callbacks. For that reason the Fragment is allowed to talk to the View directly.

Gimme some 'samples

Y'all want some examples, sure why not. Most of you ain't reading all this filler talk anyway. Reading? Ain't nobody got no time for that... Well, if you are reading it, let me know in the comments down below!

MVP requires reading, nobody has time to read up upon Model View Presenter

In the Github repo I mentioned earlier below code can be found. It's an example project which I personally use as a Skeleton for many production apps. I recommend reusing the code, so that if necessary you can tweak it to your specific use case. It contains a basic setup of Dagger, Stetho, Timber, LicenseDialog, JMockit and AssertJ. Below is an outtake of the mvp package, which is written in Kotlin. Kotlin is a new language that targets the JVM and is particularly interesting for Android developer. I have dedicated a blog post about Kotlin, part 1 and part 2, if you can read Java then Kotlin shouldn't be a problem.

Presenter

Even though the real magic happens in the Presenter, the boiler plate code of the Presenter is the easiest. The only surprise might be the ViewModel, which is just an interface the Presenter defines to abstract away the View. The View should implement this interface, as we will see in a moment. The View will also call the start and stop methods.

abstract class BaseFragmentPresenter<VM> {

    protected var viewModel: VM? = null

    fun start(viewModel: VM) {
        this.viewModel = viewModel;
        onStart();
    }

    fun stop() {
        onStop()
        viewModel = null
    }

    /**
     * Use this callback to start some operation, like database a query.
     * The viewModel is non-null.
     */
    protected abstract fun onStart();

    /**
     * Stop any running operation that might be busy in the background.
     * After this method is finished viewModel will be de-referenced.
     */
    protected abstract fun onStop();

}

Below there is an example implementation. The ViewModel defines just a single callback from the Presenter to the View. The View will have an actual instance of this Presenter, so it can just call buttonDoStuffClicked when a button is clicked. The Fragment will be responsible for instantiating this Presenter, any object the Presenter needs from the Model can be injected via the constructor.

class SkeletonFragmentPresenter(val modelInteractor : ModelInteractor)  
    : BaseFragmentPresenter<SkeletonFragmentPresenter.ViewModel>() {

    interface ViewModel {
        fun showTheUserAMessage(message: String)
    }

    override fun onStart() {
        modelInteractor.subscribeToSomethingComplex(/* Some listener */)
    }

    override fun onStop() {
        modelInteractor.unsubscribeToSomethingComplex(/* That one listener */)
    }

    fun buttonDoStuffClicked(message: String) {
        modelInteractor.executeSomeComplexAsyncOperation (message) {
            viewModel?.showTheUserAMessage(it)
        }
    }
}

This way your business logic doesn't need to worry about complex lifecycle things, or the nitty gritty details of preparing UI widgets. This helps a lot with testing as well, because during tests you can just insert a mock instead of having actual view objects. No-UI integration tests also become easier, since you can describe more complex behaviour of the view, without dealing with UI widgets.

View

Alright, the view code is a bit more complex, but bear with me, the boiler plate may look complex, the usage is a cakewalk. The View implements the ViewModel, and the Fragment is responsible not only for instantiating, but also choreographing the execution. It will call inflate when the View must be inflated, and deflate when it is no longer needed. In between the Fragment will let us know when the Android UI is ready via androidViewReady and to start and stop, so we can let the Presenter know. Just to be sure we will stop the Presenter also when deflate is called, because there are edge cases (like screen rotation) where the lifecycle behaviour of the Fragment is a bit quirky.

abstract class BaseFragmentView<VM, P : BaseFragmentPresenter<VM>> {

    protected var rootView: View? = null
    protected var presenter: P? = null

    open fun inflate(inflater: LayoutInflater, container: ViewGroup, @SuppressWarnings("unused") savedInstanceState: Bundle?): View {
        rootView = inflater.inflate(getViewId(), container, false)
        return rootView!!
    }

    fun androidViewReady() {
        if (rootView != null) {
            prepare(rootView!!)
        }
    }

    fun deflate() {
        stop()
        rootView = null
    }

    fun start(presenter: P) {
        this.presenter = presenter

        val viewModel = getViewModel()
        presenter.start(viewModel)
    }

    fun stop() {
        presenter?.stop()
        presenter = null
    }

    /**
     * Return the view id to be inflated
     */
    @LayoutRes
    protected abstract fun getViewId(): Int

    /**
     * Create and return the implementation of the ViewModel
     */
    protected abstract fun getViewModel(): VM

    /**
     * Convenience method so that the implementation knows when UI widget can be obtained and prepared.
     */
    protected abstract fun prepare(rootView: View);
}

The implementation is below, compared to the code above it is way easier. First we define the generics, which ViewModel we implement and which Presenter we use. Next we define the viewId which need to be inflated. During the prepare method we set the click listener, which uses the Presenter in the callback. Lastly we implement the ViewModel in which we just show a message to the user.

class SkeletonFragmentView()  
    : BaseFragmentView<
        SkeletonFragmentPresenter.ViewModel,
        SkeletonFragmentPresenter
    >() {

    override fun getViewId() = R.layout.fragment_skeleton

    override fun prepare(rootView: View) {
        rootView.buttonToast.setOnClickListener {
            presenter?.buttonDoStuffClicked(rootView.editTextMessage.text.toString())
        }
    }

    override fun getViewModel() = object : SkeletonFragmentPresenter.ViewModel {
        override fun showTheUserAMessage(message: String) {
            Snackbar.make(rootView, message, Snackbar.LENGTH_LONG).setAction("Action", null).show()
        }
    }
}

Even though the base class might look somewhat complex, the actual uses abstracts away all that complexity. The implementation is reduced to merely configuring, from there on more complex UI elements (like a RecyclerView) can be added. The focus of the implementation of the View is now to show the user content from the system (via callbacks of the Presenter) and to inform the system (Presenter) about user generated events.

Fragment

The final piece of the trinity is finally here. This is where Android hooks into your app, and where you have the ability to create a nice, loosely coupled design, or to stick with what you know and make a complex piece of... code. The Fragment needs to instantiate the View and the Presenter with it's Model interactors.

The callbacks onCreateView, onViewCreated and onDestroyView instantiate and trigger events on the View. onResume and onPause are chosen to create the Presenter and start and stop the View. Since we use onResume and onPause make sure that the Presenter can handle it.

abstract class BaseFragment<  
        VM, 
        P : BaseFragmentPresenter<VM>, 
        V : BaseFragmentView<VM, P>> 
    : Fragment() {

    var view: V? = null
    var presenter: P? = null

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup, savedInstanceState: Bundle?): View? {
        view = createView()
        return view!!.inflate(inflater, container, savedInstanceState)
    }

    override fun onViewCreated(androidView: View?, savedInstanceState: Bundle?) {
        view?.androidViewReady()
    }

    override fun onDestroyView() {
        super.onDestroyView()
        view?.deflate()
        view = null
    }

    override fun onResume() {
        super.onResume()
        if (view != null) {
            presenter = createPresenter()
            view?.start(presenter!!)
        }
    }

    override fun onPause() {
        super.onPause()
        view?.stop()
        presenter = null
    }

    abstract fun createView(): V
    abstract fun createPresenter(): P
}

Now look at how simple and elegant creating this loosely coupled system is. The implementation only needs to create the View and Presenter and that's it. The entire complex lifecycle caught in two methods!

class SkeletonFragment  
    : BaseFragment<
        SkeletonFragmentPresenter.ViewModel,
        SkeletonFragmentPresenter, 
        SkeletonFragmentView
    >() {

    override fun createView() = SkeletonFragmentView()

    override fun createPresenter(): SkeletonFragmentPresenter {
        val modelInteractor = ModelInteractor(/* What ever you need */)
        return SkeletonFragmentPresenter(modelInteractor)
    }
}

Dependencies

Somewhere in the beginning I mentioned Focussed, Readable, Maintainable, Reuseable, Testable and The works. Also I mentioned minimal ceremony. With the above reusable code the required ceremony is reduced to mere configuration. It simplifies complex lifecycle events to concrete callbacks. Next to that it improved ease of testing and aids to speeding development and finding issues. But how can we figure out if this is really really true? Let's look at the dependency graph of this system

Model View Presenter Fragment overview of dependencies

Look at how dependent the Fragment is! All we did was extract complexity and still it is this highly dependent! Can you imagine how hard the complexity of the Fragment can become if you mix all these responsibilities? It is by design dependent on Android, we even extend an Android base class, so we are tied to the OS. But next to that we shouldn't want more complexity in this class.

The View reduces some complexity, though it is still dependent on Android. All the UI widgets are Android components, so there is now way around these dependencies.

The Model/Interactors might be dependent, there is a weak link to the Database, Backend, etc. But we are free to inject these into these classes so we can choose how dependent these classes are.

Finally the Presenter has some dependencies on the Model, but the Fragment injects these, so these are also rather weak.

Look at all the seams we introduced, all of these seams are nice entries for all sorts of types of testing, contributing to Testability. Each class has a clear scope, a clear responsibility, they are Focussed. Knowing what a class is supposed to do, and realizing that in a few lines of code makes it Readable. Composing business logic in blocks helps Reusability, but also you can swap a different View via the ViewModel into a Presenter, and you can completely change the UI layout without the need to worry about changes in behaviour. This loosely coupled design aids to Maintainable code. Finally, when reusing the shown code, you get The works for free.

Conclusion

This implementation of Model View Presenter tries to cut down on all ceremony necessary to create a nice design, but as said in the beginning, there is no silver bullet. There might be some additions you need, or some changes. For example you might need some more lifecycle events in your Fragment; Perhaps you want to catch menu events, or need to use onStart/onStop instead of onResume/onPause. That's why I recommend using the source in your own project, instead of a ready to go gradle include. You can go a long way with extension functions, but often you need more flexibility since this pattern is in the core of your UI code.

Once you configure the Fragment and View the fun part starts. The Presenter will make implementing, or combining, your business logic way easier then when you did it all in the Fragment. Also the testability is greatly improved, since the Presenter is just a POJO (or should it be called a POKO now?). I recommend not to test the View too much, since unit testing animations and edit texts doesn't bring you much, other than a headache.

I've been using this pattern for years already, it never let me down. Often I thought that a Fragment was too simple for MVP, but almost always, after a short while I needed to redo the implementation with MVP. In a really short time span a Fragment can get more and more complexity in it's internals, that you really need to have a flexible setup to accommodate for that.

References

If you want to read more, have other views, and find more interesting content:

Fragmented podcast with Israel Ferrer
Fragmented is a podcast targeting Android developers. In this episode Israel Ferrer talks about 'Android development like a pro'. Amongst other things they discuss Model View Presenter.

My Skeleton Github example
My github contains a repo with a Skeleton App. It contains amongst other things to code above. It also utilizes Dagger, Stetho, Timber, LicenseDialog, JMockit and AssertJ. For just the MVP code look here.

Kotlin, superseding the language we love
A two part post about Kotlin, starting with the basics. Part 2 continues with the more advanced stuff. Kotlin is 100% interoperable with Java, so if you want to use the code from the Skeleton project with your Java code, you can.