Even though mobile applications look quite simple for users, there is much complexity hidden behind the veil of neat UIs. An app may be focused on any task, but it should stick to one basic requirement – the clean architecture. Facebook app is a great example of this concept. It is sustainable and highly adjustable to market shifts or company growth. All due to its thorough approach to architecture.


Know the Basics: clean architecture in Android

So, what clean architecture exactly is? It requires a set of development measures that allow creating a working product:

  • it doesn’t depend on any carcasses, user interfaces, 3rd party databases, or supervisor organizations;
  • it is good for testing.

Now, here is a brief look at the rule which explains what source code development participants are and how they depend on each other. See the circles to get the idea of the vector. There may be more layers of the scheme, but it depends on a case.

The following descriptions will help to understand the image.

  • Entities – they are business elements of an app;
  • Flow – this word shows the stream of data which goes back and forth from Entities. Flow is driven by use cases;
  • Converters – these are the means which make information format most comfortable for entities and flow interactive functions. They are also called interface adapters;
  • Attributes – things which build UI: drivers, instruments, frameworks, and other details, that englobe connections with APIs, databases, etc.


Follow the arrows, because the rule says that outer layers support inner ones, as business elements can only receive data from outer circles.


Example model

I was puzzled about the idea of a working model scenario, and my friends from Freepps.top helped me with that. So here it is: imagine the app, in which you can see a list of company employees. Tapping on each of them opens a new window with personal info requested from the cloud. Take this scenario into consideration, while reading further.


Layers of Architecture

It’s important to keep in mind, that rules of business should be unaware of any outer circumstances. Despite that, these rules are independent of any objects from the outside during tests.

To implement the condition, I suggest dividing the whole project into 3 separate layers. Each of them contains specific aims and can function by its own.

Mind that every layer is endowed with unique data model properties. That’s why they are able to avoid dependence. In the end code, you have to apply data schemer for data formatting. It would help to prevent unwanted cross-use of models.

See the schematic depiction of the process and remember that there is no need to reinvent the wheel:


domain layer clean architecture

Layer 1: Presentation

This layer contains coordinators, which drive visual components. So, this is where image generation (rendering) is. The whole process is conducted by particles and actions which don’t actually have inner logic except UI logic. A presentation may be based on such patterns as Model-View-Presenter (MVP iOS), Model-View-Controller (MVC) or Model-View-ViewModel (MVVM). For further descriptions of these patterns check out links as I can’t go into details.

Computing and showing data on the presentation layer is done by converters (see image 1). They are the performers of tasks, that appear in new outer lines that come from and to central lines of Android UI.

model presenter view

Layer 2: Domain

This one contains all the logic processes. You would also find all of the related converters’ embodiments (use cases) here. It’s the place for all rules of business.

Technically it’s an elementary piece of Java code, which doesn’t have any Android reliances. So, any outer essentials resort to using interfaces only at the time of linking to business objects. 

interactors clean architecture


Layer 3: Data

User Storage realization provides itself here for a transition of all the data which is necessary for the application. At the time, the interface is in the previous layer. Realization uses special storage (repository) pattern which is aimed at choosing appropriate roots of data in dependence on particular current circumstances.

Here is an example. A random user is chosen by his id. In cases, if this user is already listed in the disk cache, the pattern would pick cache as a data root. In other cases the data is absent, so app’s cloud would be requested to bring the needed data to use it and save it into the hardware cache.

The fact is that no users are able to see the original source of data. It’s completely invisible for them, and they don’t really care whether it comes from hardware storage or app’s cloud. There is only one thing that matters: the data is requested and delivered to the customer. That’s it. Note that there are many ready-made tested libraries for this kind of task, so don’t waste time building a new one.

storage realization


Approach to Errors

There is no unambiguous answer to this problem, so we at Freepps.top will be grateful for your suggestions in comments.

The main method is to apply callbacks, but problems with data storage may happen, for instance. That’s where you can apply callback 1 [onResponse()] or 2 [onError()].

The second variant contains special cases folder class which is named “ErrorBundle”. However, this method may cause some troubles, as raws of callbacks may appear multiple times before an error reaches a rendering stage in the first layer. End code may become not readable enough.


Test it

Each layer has its own approach:

  • Layer 1 – Espresso, please! (for UI testing) and JUnit + MockK (for presenters);
  • Layer 2 – JUnit + Mockito;
  • Layer 3 – Same as layer 2.


Conclusion: Clean Architecture in Android

Robert Martin once said that clean architecture is not about using frameworks but about purposes, and it’s totally right. At the same time, it would be fair to mention that there are always multiple ways of realization of anything. Creators like you handle tons of routine difficulties day after day, so methods from this article would make your work faster for sure. Your app would be convenient:

  • To support;
  • To test;

Try to implement your ideas with these suggestions to give it a good strength test and, maybe, find some improvements. There’s no limit to perfection, but it’s impossible without the use of existing stuff. Remember that your feedback can make the realm better!

Author’s bio

Daniel Wilson’s work at Freepps.top is not only about testing apps’ features because it’s a way to nowhere. That’s why he regularly uses spare time to attend courses and broaden my programming horizons.

If you are interested in knowing more about Clean Architecture in Android, I highly recommend you to subscribe to our newsletter