Android Architecture Comparison: MVP vs MVVM

Building a high quality, maintainable and performant mobile app should be the goal of any serious developer. Following a recognizable and easy-to-follow design pattern is a great way to build your app from the ground up. We want to be able to revisit our codebase in 6 months and still feel confident that we can build upon or extend our apps if we need to. Additionally, we want to make it easier for new developers to join the team or project and be able to pick things up quickly.

As consultants, we also want to make sure that each time we deliver a codebase to a client, that it is easy to maintain, extend and augment in the future if necessary.

Architecture patterns are established designs and ways of structuring an application in order to minimize bugs, make code easier to read, understand, and test.

We’ll explore two of the most commonly used mobile app design patterns in this post, Model-View-Presenter and Model-View-ViewModel

Model-View-Presenter

MVP emerged as one of the “successors” of the classic Model-View-Controller pattern used in web and early mobile days.

One of the issues early mobile developers would run into when using MVC was that controllers would grow large and unwieldy. On Android, this would mean complex and often large Activity classes that did way too much and knew about too much.

MVP aims to provide more decoupling of components, and to make each part of an application know only what it needs to. As the name suggests, MVP is composed of 3 main components.

Why do we need this? Why is it a good idea to structure our app so that it is composed of individual, self-contained pieces?

Well for one, this makes testing much easier. When core pieces of your app architecture are decoupled from other pieces, this makes it much easier to test each component in isolation. In the case of MVP, you will now be able to test your Presenters, since they are not tied to any Android SDK components (you should try your best to ensure this).

Model As you might’ve guessed, your Model represents your data layer. Objects, classes or structures that hold information in your app. This can be POJO classes in the case of Java, or data classes in the case of Kotlin.

View As the name suggests, your View represents your UI that your user will see and interact with.

Presenter The Presenter is the glue that connects both the View and Model. It acts as a sort of middle-component that is notified of user interaction, updates the Model layer, and then tells the View when it needs to update based on changes in the underlying data.

Presenters usually have a one-to-one relationship with Views. For each View in your app, you normally would create a Presenter interface for that View. We can quickly see how the codebase can grow quite large for view-heavy applications.

Imagine you were creating a simple news feed application, that loads a list of articles in a RecyclerView. You might create a Presenter to back your main feed view like this

interface MainFeedPresenter {

 fun loadArticles() : ArrayList<Article>

}

Then, you would implement your interface and inject your View(Activity or Fragment) like this

class MainFeedPresenterImpl(val view: MainFeedView) : MainFeedPresenter {

  override fun loadArticles(): ArrayList<Article>{

   val articles = ArrayList<Article>()
   val jsonString = BetterNewsApplication.applicationContext().assets.open("articles.json").bufferedReader().use {     it.readText() }

   val gson = Gson()
   val jsonObject = JSONObject(jsonString)
   val jsonArray = jsonObject.getJSONArray("articles")


   for (i in 0 until jsonArray.length()){

     val articleJsonObject = jsonArray.getJSONObject(i)

     // Convert each article string to an Article model object
     val articleObject = gson.fromJson(articleJsonObject.toString(), Article::class.java)

     articles.add(articleObject)
   }

   // Tell our View to update the UI
   view.displayArticlesList(articles)

   return articles
 }

}

Model-View-ViewModel

MVVM is another popular architecture pattern that proved to be very useful over the years. Similar to MVP, it is composed of 3 main parts.

Model Just like in MVP, your Model represents your data layer. Objects, classes or structures that hold information in your app. This can be POJO classes in the case of Java, or data classes in the case of Kotlin.

View Again as with MVP, the View layer represents the UI and what the user sees.

ViewModel This is where MVP and MVVM differ. ViewModels, unlike Presenters, can be shared across multiple Views. Imagine you have a multi-step section of your UI, something like a wizard flow during onboarding or completing a purchase. You can create a single ViewModel class that would act as the backing for each View within the flow.

ViewModels can also be made more powerful when used in conjuction with LiveData objects, which are lifecycle-aware data holders for Android.

You can create and implement your own ViewModel interface, or leverage Android Jetpack’s ViewModel from the Architecture Components library.

Which One Should I Choose?

The debate about which architecture pattern works the best is a time tested one, and probably won’t end anytime soon. Software development is a deeply creative process, and I’ve found that it’s best to never let yourself become too dogmatic about your approach to building things.

The design pattern that’s going to work best for you will depend on a few key factors that require a concerted amount of thought.

How complex is the product you’re building? How large is your team? Will unit testing be a priority now or in the future? Will this product need to be extended or changed at some point? Is it open sourced?

These are just a few of the questions I like to ask myself before I decide on the best way to structure an app.

Every approach and pattern has pros and cons, and the process of weighing these options and making a decision should be just as enjoyable as writing the code itself.

Happy coding!