Chapters

Hide chapters

Advanced Android App Architecture

First Edition · Android 9 · Kotlin 1.3 · Android Studio 3.2

Before You Begin

Section 0: 3 chapters
Show chapters Hide chapters

7. Model View Presenter Theory
Written by Yun Cheng

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

As you saw in the MVC chapter, although the MVC architecture pattern theoretically allows an app to achieve separation of concerns and unit testability, in practice, MVC didn’t quite work on Android. The problem was that the Android Activity, unfortunately, served the role of both View and Controller. Ideally, you would want to somehow move the Controller out of the Activity into its own class so that the Controller can be unit testable.

One architecture pattern that achieves this goal is MVP, which stands for Model View Presenter, and is made up of the following parts:

  • Model is the data layer, responsible for the business logic.
  • View displays the UI and listens to user actions. This is typically an Activity (or Fragment).
  • Presenter talks to both Model and View and handles presentation logic.

The Model-View-Presenter pattern

With MVP, the Model remains the same as with the MVC architecture. The Model is the data layer, and is responsible for the business logic: retrieving the data, storing the data and changing the data. In your sample project, your business logic revolves around movies, so the Model is composed of the Movie data object, the LocalDataSource, which interacts with the local database. It is also composed of the RemoteDataSource, which interacts with the Movie Database API over the network.

The View is also the same as with the MVC architecture, responsible for displaying the UI, except that, with MVP, this role is specifically designated to an Activity or Fragment. The View will hide and display views, handle navigating to other Activities through intents, and listen for operating system interactions and user input.

The Presenter is the glue class that talks to both the Model and View. Any code that does not directly handle UI or other Android framework-specific logic should be moved out of the View and into the Presenter class. For example, while the View will listen for button clicks, the presentation logic of what happens after a user clicks a button should go into the Presenter class. Similarly, when the Model has updated, it is not the responsibility of the Model to know how the View ultimately wants to display the data.

It is the Presenter’s job to do any additional mapping or formatting of the data before handing it to the View to display it. This kind of logic is known as presentation logic, and it is handled by the aptly named Presenter.

While the View extends from san Activity or Fragment, the Model and Presenter do not extend Android framework-specific classes, and, for the most part, they should not contain Android framework-specific classes. In other words, there should be no references to the com.android.* package in the Model or Presenter. As you will read later, this rule allows for both the Model and the Presenter to be unit tested with this pattern.

The Presenter should not contain Android framework-specific classes
The Presenter should not contain Android framework-specific classes

In summary, with the MVP pattern, the roles of the Model and the View are equivalent to those in MVC, except that now the Activity or Fragment is explicitly designated the role of the View. The Controller has now been replaced with a Presenter class, which, based on the definition above, seems to serve a similar role as the theoretical Controller.

However, there are several key characteristics of the MVP pattern that differentiate it from MVC and allow for it to work in Android: the order in which events occur, the breaking of the ties between View and Model and the use of interfaces.

The MVP flow

To use MVP, you’ll need to reimagine the order in which events occur in the flow of an Android app. Unlike in MVC wherein the Controller is supposed to be the main entry point for the app, the main entry point is the View.

MVC flow
FPV wcim

fun onClickAddMovie(view: View) {
  ...
  presenter.addMovie(title, releaseDate, posterPath)
}
override fun addMovie(title: String, releaseDate: String, posterPath: String) {
  val movie = Movie(title, releaseDate, posterPath)
  localDataSource.insert(movie)
  ...
}
override fun addMovie(title: String, releaseDate: String, posterPath: String) {
  val movie = Movie(title, releaseDate, posterPath)
  dataSource.insert(movie)
  view.returnToMain()
}

Separation of concerns and unit testing

As the example above demonstrates, the Presenter serves as a middleman between the Model and the View, shuttling information and updates between the two classes. Because the Presenter handles these responsibilities, the Model and the View do not need to be aware of each other. By breaking the direct tie between the Model and the View, MVP allows for better separation of concerns.

Using interfaces

With the exception of Android Architecture Component classes, which are allowable in Presenters, the Presenter should not contain references to any Android framework-specific classes, such as Context, View, or Intent. This rule allows you to write regular JUnit tests on the Presenter. However, the Presenter, of course, needs to talk to the View, which means it needs a reference to the Activity, an Android framework-specific class. How can you get around this reference to an Android class when you write your unit tests?

Create interfaces for the Presenter and View
Yxaoge utlitjegoy fot hwe Hcovejgal ecx Gieq

MVP advantages and concerns

By dividing an Activity into separate Model, View, and Presenter classes with interfaces, you are able to achieve separation of concerns as well as unit-testable Models and Presenters. These are certainly considerable achievements, even if it means having to navigate through interfaces, which can be confusing at first. In Android Studio, CMD + OPTION + B on Mac or CTRL + ALT + B on PC is the keyboard shortcut for finding your way to actual implementations of interface methods.

Key points

Where to go from here?

In the next chapter, you will apply your knowledge by rewriting the Movies app using MVP. The exercise will set you up for writing more unit tests for the app that previously were not possible without this architecture pattern.

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2024 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now