ProAndroidDev

The latest posts from Android Professionals and Google Developer Experts.

Follow publication

Clean Architecture for mobile: To be, or not to be

As an Android developer, technology enthusiast, I’m always learning some new things which can help me in creating well organized, maintainable, and scalable codebase.

Recently I tried developing an entire application using the Clean Architecture, as the application is completed now I am taking a moment to analyze the impact of Clean Architecture. So let’s begin the journey of finding the answers for the question of the era, Clean Architecture: To be, or not to be 🤔

Quick Overview: What is Clean Architecture?

I have seen the videos of our beloved Uncle Bob Martin several times just to understand the concept. Based on that, we can divide our entire system in the Domain, Data & Presentation layer.

Presentation Layer: This layer includes your activities, fragments and view model, etc. Mainly the UI related stuff.

Data Layer: This layer includes your database, shared preferences, network calls, and location-related services, etc.

Domain Layer: This includes use cases and entities. This layer has the entire business logic that resides in it. The entire application will evolve around this layer.

Dependency Rule

As you can see in the following diagram Presentation and Data layer will be always dependent on the Domain layer. The domain layer needs to be independent of the Presentation and Data layers.

We can easily found the blogs explaining the pros of using Clean Architecture but there is so little to be said about the pitfall and constraints that it enforces. I will mainly focus on the pitfall and constraints of using the Clean Architecture, I hope it will help you make the correct choice of architecture.

Firstly, If you listen carefully to Uncle Bob’s talk, you will quickly realize that he suggesting us to apply Clean Architecture to the entire system i.e. back end and front end. Also, he says for UI layer use the MVP or MVVM architecture. Mobile applications that we develop is nothing but the UI for our systems.

Before opting for the Clean Architecture you must consider the following points to avoid the overhead of complexity and writing boilerplate code.

Can we remove the domain layer or make it optional?

I know a lot of eyebrows will be raised with this sentence. Generally, all the complex business logic is handled on the back end side. There is not much to handle on the front end, except some validation and simple mathematical calculations.

In the project I worked on, we have around 100 use cases, out of which 90 use cases just have a code for accessing the repository layer. The remaining 10 use cases are mostly for the validation data enter by the user in different forms. Also out of those 10 use cases no use case got reused.

Similar to our project, if the complex business logic handled by the server then you should give a serious thought of using MVP or MVVM kind of architecture. Clean Architecture in this type of project will demand you to create a lot of boilerplate code, use case, mapper, entity and test cases, etc. Writing those classes is error-prone and time-consuming.

Also, if your project has a strict deadline, people will find the shortcuts to achieve the functionality. I have seen the data entities used in the presentation layer, which will violets the dependency rule. Someone might argue that through code review should be done to avoid it, but when you have unrealistic targets and jobs on the line most ethical people will also choose the shortcuts. Please don’t miss considering the deadline while deciding on architecture.

For some projects, there might be some small amount of business logic which can be reused. In such cases even using MVP or MVVM we can create a common class for it, whether to call it use case or not is I will leave up to you.

By removing the domain layer I mean using MVP or MVVM and by making it optional I mean creating a class of reusable business logic.

What about the dependency flow and separation of layers?

While using MVVM or MVP, we can use the repository pattern which ensures the decoupling of data and UI layer. It will solve the issue of constantly changing APIs and structural modification in the database.

In my five year career, I have seen API changes more frequently than the UI. The API needs to provide support for various channels like mobile, web, etc. There are bound be some changes in the definition of API as we make progress. Aesthetic changes in UI will not require any change in the entity returned by the repository, the view layer can easily handle those.

So I can say that we can achieve the desired dependency flow and layer separation using MVP or MVVM.

What about frameworks and third party libraries?

You can say for certain that a piece of code that you’re not in control of will make your life harder. Generally, those are libraries and frameworks which we are using.

The library or framework creator constantly tries to update their library for adding new features and enhancing it. As a result of this, there will breaking changes along the way, which will force you to change the dependent code or in the worst case switch to another library due to compatibility issues.

To overcome this we can hide that dependency using a class or interface so that the change in the implementation of a single class will result in changes in the entire code base. This concept is a standalone thing, we can achieve it with any kind of architecture or even without any architecture.

While finding the candidates for this abstraction consider the frequency at which the library can change, the number of classes dependent on it, the amount of effort needed if there is some breaking change.

E.g. in one of my projects, we started using Retrofit 1.9, soon after Retrofit released 2.0. After updating the latest version everything got broken. We have to make the changes in almost all of the activities as there was no architecture in place. Such libraries with a wide range of reach in the codebase are the prime candidate for it. Similarly, we can abstract the library for loading images from the internet e.g. Glide, Picasso, etc.

On the other hand, I have used a library MPChart for displaying the charts. It is used only once in the entire application and that too in UI, so it doesn’t make any sense to abstract it.

Will there be layers and boundaries?

In MVP or MVVM, we can create data and presentation layers with ease. Even we can have a clear architectural boundary between them. If you are not having a large amount of business logic on the front end there is no need to have a domain layer. Two layers can suffice your need and can create a scalable application.

Can we have a separation of concerns and responsibility?

Separation of concern says that a component should have only one reason to change — one responsibility. Classes belonging to the database should have nothing to do with the UI or the networking components. They should be isolated. This can be easily achieved with MVP or MVVM and a repository pattern.

We can make the UI so dumb it should not contain application logic, but it will responsible for formatting, and make decisions on how to present them to the user. View Model or Presenter can help us with this.

What about maintainability?

I am considering mainly two factors under maintainability, ease of making changes & adding new functionality. For the small project, where complex business logic is handled on the back end, you will find many duplicate entities. For each layer you create a separate entity, but under the hood, they are all similar. This will increase the size of the APK and the application’s memory footprint.

Making changes in such a project will have a larger impact as classes in different layer needs to be modified for a single change. This will be a repetitive and boring task. Even with MVP or MVVM, if proper care is taken we can structure our code is a way that we can easily add new functionality.

What about testability?

Using the mocking frameworks and testing library, we can make code written in MVP or MVVM architecture 100% testable. By mocking the behavior dependent classes we can decrease the execution time.

I am not saying that Clean Architecture is of no good for mobile application development. I am just trying to show another perspective.

Clean Architecture is not a silver bullet solution for all architectural needs. Do not get carried away by trends in the community when making the decision. For most projects MVP or MVVM is good enough to create a scalable and maintainable codebase.

You should decide based on the nature of your project. For example, if your project is big and complex, has a lot of business logic on the front end then Clean Architecture brings clear benefits.

On the other hand, for smaller and simpler projects, you will just end up writing more code and adding complexity with all the layers, investing more time along the way.

Let’s not make the cure worse than the disease. Take a wise decision considering the above points. I hope you will find them useful. If you feel I missed any point in the article, please do let me know in the comments.

Published in ProAndroidDev

The latest posts from Android Professionals and Google Developer Experts.

Responses (2)

Write a response