Andy loves Clean Architecture

How to implement a Clean Architecture on Android

Learn how to implement a Clean Architecture on Android from scratch

Manuel Mato
Published in
8 min readMay 23, 2019

--

What will you find in this article?

In 2016 I started studying Java and at the beginning of 2017, Android. From the beginning, I already knew that the software architecture existed but not how to apply it in my code. I looked for several tutorials but they did not seem clear enough so that someone with little experience could start doing good practices.

For this, what you will find in this post is the article that I would have liked to read when I was starting so that my past me could mount a clean architecture on Android in an easy way.

The importance of software architecture

Many companies do technical tests to candidates who are submitted to a selection process. The tests may vary, but there is something that never changes, and that is that they all ask for good practices, including applying good software architecture.

A good software architecture allows the system to be easy to understand, to develop, to maintain and to implement [Clean Architecture, Chapter 15].

The goal of this article is that someone who has never used the software architecture on Android will learn how to do it. For this I will give a practical example, the least favorable solution and a more optimal solution applying architecture.

The example:

Items en una RecyclerView en una arquitectura limpia en Android

1. We will consume data from an API and show the results to the user.

2. The results are a list of beers with your name, description, image and alcohol content.

3. Beers must be ordered from lowest to highest grade.

To solve this problem:

  1. We must obtain the data from the API
  2. Once we have the data, we must order the items from lowest to highest ranking
  3. If the graduation is less than five, a green circle will be painted, if it is between five and eight degrees, the circle will be orange and for all other cases, the circle will be red.
  4. Finally, we must show them in a list.

What is the least favorable solution?

The least favorable solution is to create a single class that does the four previous points. That solution is what any of us would do without knowing that the software architecture exists.

The result for the user will be the same, you will see a list ordered on the screen, but if we need to scale this system, we will realize that the structure is not easy to understand, develop, maintain or implement.

How can I understand the software architecture in Android?

I’ll give you a very simple example. Imagine a car factory with five zones:

  1. A first zone creates the chassis
  2. A second zone joins the mechanical parts
  3. A third zone assembles the electronic circuit
  4. A fourth area paints it
  5. And one last area adds the aesthetic details

This means that each zone has its own responsibility and they are working in chain from department one to five, to obtain a result.

One of the advantages is that once the car is finished, if it presents an error, according to its behavior we will know which department has to fix it, without bothering the others.

Also if we want to add more aesthetic details, we will go directly to department five, or if we want to change it, we will go to four … and even if we change the chassis, it does not imply that it will change the way of working of the painting area. That is, we can modify our car without the whole factory knowing what they are doing or how the rest of the areas do it.

Also, if over time we want to open a second factory to build a new car model, it will be easier to share the work areas if we need it.

Applying software architecture on Android

What we are going to achieve is that there is not a single class doing all the development work: ask for the API data, sort them and show them on the screen, but it will be distributed in several areas called layers (represented as packages)

What are those layers?

Layers of a clean architecture on Android with ViewModel in the presentation layer

For this example we are going to create a clean architecture that consists of three layers that are subdivided into five:

The presentation layer

The business logic layer

And the data layer

1. The presentation layer

The presentation layer is the user layer, the graphical interface that captures the user’s events and shows the results. It also performs operations such as verifying that there are no formatting errors in the user’s data entry and formatting data to be displayed in a certain way.

In our example, these operations are shared between the UI layer and the ViewModel layer:

  • The UI layer contains the activities and fragments, capturing user events and displaying data.
  • The ViewModel layer formats the data so that the UI shows them in a certain way and verifies that the user’s entries have the correct format.

Instead of using ViewModel we can use another layer that does this function, the important thing is to keep the idea of ​​the responsibilities of each layer.

In our example, the UI layer shows the results of the beers and the ViewModel is the one that tells you the type of color you should use since it checks the alcoholic graduation range so that the UI knows which color to paint each one.

2. The business logic layer

In this layer all the rules that a business must comply with are business. For this, they receive the data provided by the user and perform the necessary operations. In our example, the ordering of beers from lowest to highest alcoholic strength are the business rules for what the UseCase class will do.

It is the most stable layer and the one that indicates what is happening in the software architecture developed.

3. The data layer

In this layer is where the data is and where they can be accessed.

These operations are divided between the Repository layer and Datasource:

  • The Repository layer is the one that performs the logic of data access. Your responsibility is to obtain them and check where they are, deciding where to look at each moment. For example, you can first check the database and, if they are not, search them on the web, save them in the local database and now return the saved data. That is, it defines the flow of access to the data. In our example, it asks beers directly to the data layer that communicates with the API.
  • The Datasource layer is what the implementation performs in order to access the data. In our example, it is the one that implements the logic to be able to access the API data of beers.

How do the layers communicate?

Let’s see the theoretical approach and the practical approach.

In theory:

Communication between the layers of a clean architecture on Android

Each layer should talk only with their immediate friends. In this case, if we look at the software architecture scheme:

  • The UI can only communicate with the ViewModel
  • The ViewModel can only communicate with the UseCase
  • The UseCase can only communicate with the Repository
  • And the Repository can only communicate with the Datasource

In this way we are respecting the work in the chain of the factory, each area communicates with the next immediate and never with others.

In practice:

The package structure of a clean architecture in the IDE Android Studio
  • We have a package structure where the classes are created, in which each one implements its responsibility.
  • In the user interface layer, the “ui” package, the Activity or Fragment is created. This class must communicate with the ViewModel layer. For this, the Activity must instantiate the ViewModel object and observe the declared LiveData.
  • In the presentation logic layer, the “vm” package, we create the ViewModel. This class creates the LiveData that will be observed by the Activity or Fragment. The ViewModel communicates with the UseCase layer, for this you must instantiate the UseCase object.
  • In the business logic layer, the “domain — use case” package, we create the UseCase class. This class is instantiated with the following layer, which is the Repository, but it does not do it directly with the object, but it does so with an interface that is in the UseCase package. This is because the UseCase is the most stable layer, which means that the libraries or classes that matter, must also be, and the Repository is one of the most unstable. In this way, it is the Repository that will have an import from the “domain — use case” package and the UseCase will not know it. The UseCase is at the center of the architecture, and this can be seen in the following scheme:

In our example, the Entity is the data model of the business logic layer.

  • In the Repository layer, the “repository” package, we create the RepositoryImpl class that implements the interface that is in the “domain-use case” package. The Repository calls the Datasource layer, so you must instantiate this class.
  • And finally, in the Datasource layer, the “datasource” package, we create the Datasource class that develops the logic to get the API data and return them in a data model to be able to work with them. In our example, the Datasource is instantiated with the library with which the API connection is going to be used to consume the data, so the Datasource must instantiate this library in order to call its methods.

Final notes on the software architecture

We have seen that each layer of software architecture has its responsibility and communication between them.

It is important to emphasize that at no time has there been talked of used libraries or programming languages since the architecture focuses on the correct structuring of the code so that it is scalable. The libraries change over time, but the principles of architecture are maintained.

This article is a brief introduction to architecture, but the SOLID principles must be deepened and applied them. It is recommended to read about dependency injection, to avoid instantiating the objects directly in the architecture classes and thus be able to do, in our example, Unit Testing with Mockito and JUnit.

I share a repository where you can see:

  • The example of a Clean Architecture on Android with Kotlin
  • In the presentation layer, LiveData to communicate the UI with the ViewModel
  • Coroutines to communicate from the presentation layer to the data layer
  • Kodein for dependency injection
  • And JUnit with Mockito to test the business logic

See and download the code from Bitbucket

--

--