VIPER in Android: The Practical Guide or How to Catch a Snake?

Alex Borovskoy
OmiSoft
Published in
6 min readMay 23, 2019
The picture is taken from https://www.wikihow.com

Introduction

We all try to experience the true decision on how to design our code so that it would be understandable, logical, and reusable due to loose coupling. To solve these problems, we start looking for an architectural approach, since it is well known that a good architecture allows to make an application easily extensible, maintainable, and suitable for testing.

I think the majority of Android & iOS developers are already familiar with the classical concepts of MVP and MVVM architectures, but there are still a few approaches that not everyone knows. One of such architectural approaches is considered to be VIPER.

What kind of snake is it? Is it dangerous?

VIPER is an architectural approach for iOS mobile app development based on the paradigm of Uncle Bob’s clean architecture, which gradually began to penetrate with Android.

The word VIPER is an abbreviation for View, Interactor, Presenter, Entity, and Router. It means that our logical app’s structure called a module is divided into five separate levels of responsibility. Each screen corresponds to one module. The main idea of all clean architecture templates is to create a clean and modular structure, and VIPER here is not an exception.

Let’s look at the structure of the so-called module:

Image 1. VIPER module structure

After the diagram has been learned, let’s dig into everything in detail.

Viper in client-server apps

At the moment, client-server applications are the most widespread, so in this article I am going to show an example of VIPER implementation in the app receiving data from the network. The application is written in the programming language Kotlin.

This is a very simple application with a splash screen, a main screen with a list, and a detail screen. The datasource is API from Umorili website due to which we will receive some funny posts with bash.im.

Image 2. Screen Shots of an app described in article: splash screen (1), main screen (2), detail screen (3)

The sample application is available on GitHub at the link:

So let’s look at the app’s structure.

Image 3. Structure of the project

As you can see, our application consists of three VIPER modules, namely:

  1. main
  2. detail
  3. splash

Based on the names of the modules, you can understand that while starting, the app shows a splash screen (1), and then goes to the main screen (2), which displays a list with a preview of our funny posts obtained by the REST API. Then by clicking on the list item, we go to the detail screen (3), where we display the entire post.

As you have already noticed there is another pattern called Dependency Injection (DI) used in the project for the implementation of which I used Dagger2 library. In this article, I am not going to describe the principle of the library and its components, so who is not familiar with Dagger2, I think you can additionally find a great amount of materials on this topic out there to figure it out for yourself. The only thing I will say is that I used kotlin-android-extensions and @Parcelize annotation to pass the data from the main screen with a list to the detail screen (I would recommend to wait until the technology becomes stable and not to utilize it yet).

Briefly, everything you need for using it is to enable Android Extensions Gradle plugin, add androidExtensions block to build.gradle as shown in the image:

Image 4. Android Extensions Gradle plugin

as well as add @Parcelize annotation and implement Parcelable interface.

Image 5. Entity with Parcelize notation

We have distracted a bit from the main topic, so let’s get back to VIPER.

1. Contract

First of all, we need to write a contract. This contract will describe the relationship between the components of our app module. I applied the solution offered by Google in its Android Architecture Blueprints repository. It consists of an interface with two internal interfaces, one is for View and another one is for Presenter, and as it is a good solution, I adapted it for VIPER and added an interface for Interactor and Router.

Let’s write now the implementation of our interfaces starting with View:

2. View

View is responsible for displaying the user interface and sends events provided by the user to Presenter. View described in MainContract is implemented by Activity, as in our case, or Fragment, depending on the app’s structure. Our MainActivity also contains a link for Presenter for the event handling.

Ideally, our View should not contain any logic, but only pass events to Presenter from the user and show what Presenter will say. Due to this, the testability is being much improved.

So, I truly believe you got the idea, and we can move forward.

3. Presenter

Thus, Presenter may be compared to a “director” who sends commands to Interactor and Router after receiving the data about the user’s actions from View, and also sends the data prepared for display from Interactor to View.

MainPresenter, as well as View and all other components of our VIPER module, implements the interface described in MainContract, for MainPresenter it is Presenter interface. Presenter does not depend on our View directly, but through MainContract.View interface. Presenter provides bindView (view: MainContract.View) methods in Presenter interface for adding dependencies and unbindView () for relieving dependencies.

In general, this is the same Presenter as in the MVP pattern, except that our Presenter has two more dependencies provided by Dagger, namely, Router and Interactor.

4. Interactor & Repository

Interactor contains all business logic required for the functioning of the current module, i.e. Interactor will retrieve the data from the source, convert it into ready-to-work one, and return it to Presenter. To share the work entrusted to them and increase testability, another layer called Repo (Repository) was added which is responsible for obtaining the data.

The repository may not be the only one, everything depends on our requirements. This is another pattern in our project called Repository pattern. Repo is injected into Interactor and ultimately serves as a facade that interacts with Repo and transmits the data received from it to Presenter.

5. Router

Router handles commands from Presenter to navigate between the screens. Everything is quite simple here: Router receives a command from Presenter and, having a link to Activity, navigates through the app views. It is also worth mentioning that Router is responsible for passing data between screens.

6. Entity

Entity refers to model objects used by Interactor. It is the simplest element of our VIPER structure. This is the data class that you saw in the Image #5 when I talked about @Parcelize annotation.

As a result, we obtain the following class diagram:

Image 6. Class diagram of Main module described in the article

You may also view the whole application code here https://github.com/OmiSoftNet/AndroidViperTemplate

Wrap-up

Now let’s summarize what we have talked about. So, to create the VIPER module, at first we describe Contract, then we can create our “director”, namely, Presenter, and afterwards the other components, in particular, View, Interactor, and Router.

After having understood the VIPER architecture, I assume you will appreciate all its advantages.

So what the benefits do we get?

  1. Convenience of scaling
  2. Maintainability
  3. Testability
  4. Cleaner and clearer code
  5. Improved teamwork (everyone works in his/her own module)

In this way, all above mentioned allows us to create good and high-quality products.

I hope you enjoyed the article and I succeeded in telling you about VIPER architecture. So, if you have any comments, I will be pleased to receive some feedback from you with any suggestions on how to improve the architecture, as well as I’m looking forward to Pull Requests with suggestions here.

Tap the 👏 button if you found this article useful!

About the Author
Alex is a member of Android Team at OmiSoft. Being a fan of Uncle Bob, he always tries to implement new architecture approaches.

Need an Android mobile app with clean & maintainable code? Click here to get an estimate! Or find us on Facebook and Twitter.

--

--