Implement Clean Architecture in Android

Nishchal Visavadiya
Simform Engineering
6 min readJan 31, 2023

Software architecture defines a set of rules for writing software, which helps the developer to structure the code in a well-mannered way so that the software is reliable and scalable.

It helps determine various qualities such as scalability, performance, security, code reduction, etc., and analyze and mitigate design risks. Software architecture acts as a blueprint for the design and implementation team.

The most commonly known software architectures are:

  • MVC (Model-View-Controller)
  • MVP (Model-View-Presenter)
  • MVVM (Model-View-View-Model)

Google recommends using MVVM for building robust, production-quality Android applications.

Pinpoint: The MVVM pattern is good to start with, but as the code complexity increases, we need more powerful architecture to handle the complexity as per the requirement of the code base.

That’s when Clean Architecture comes into the picture!

The Clean Architecture

Architecture is about knowing what not to write, not about what to write.

Clean Architecture by Uncle Bob

Clean Architecture basically focuses on the separation of concerns. There is no specified number of layers while following the Clean Architecture. You can add as many layers as you want. The rule of thumb is that the inner layer should not refer to any of the outer layers and as we go toward the center, the details should become abstract.

In the above image, the outer layer consists of detailed implementation, while the inner layer focuses on abstraction. This approach separates the business layer from the low-level dependencies of actual tools we use while developing the software.

The software should be such that when we change the development tools (the type of hardware and database used), it should not affect the code that defines the business logic. Clean Architecture works on this general idea.

We can imagine the Clean Architecture layer as a sphere that fades in as we go toward the center. The center has no concrete details of how any specific task is handled. It just defines the rules/policies that should be followed by the software (and that is the business logic of the software).

The below comment in the Clean Architecture book neatly summarizes this whole point.

In a clean arch, modules that contain high-level business logic/policies should be independent of the low-level modules.

The Dependency Rule

The layer should never reference anything in the layer above it. The outer layers should depend on the higher order of ideas which is contained in the inner layer.

Entity

Entities are your business rules which can be described by class, objects, data structures, or combined. When there is a change in the outer level details (e.g., operations flow), these are the most unlikely to change.

Use Cases

Use cases contain the application-specific business rule. These rules help us convert our business rules in the Entity layer to application-specific operational rules.

Interface Adapters

This layer converts the data from the use case to be used for framework layers, such as GUI frameworks, Web UI, etc.

Frameworks and Drivers

Generally, we don’t need to write code in this layer as it is the outermost detailed implementation of the used frameworks and databases.
This layer mostly contains the code that glues the code from the inner layers, which defines how the data is fetched and converted for representation.

It is not necessary to use these layers with the given name everytime we use the Clean Architecture. We can name them differently, but the dependency rule should always hold true.

Advantages of Clean Architecture

  • It makes it easy for the system to change.
  • Business logic is totally separated from other layers in the code base, and other layers depend on the business rules, making it easy for the system to add/update features.
  • The code is decoupled so that you can treat every layer as a black box, helping in testing code.
  • Every module defines its purpose rather than its details. This helps understand what an app does rather than going in-depth into the technical details.

Disadvantages of Clean Architecture

  • This isn’t a preferable choice for simple projects. If the project isn’t complex, we would unnecessarily create files and write code that can be achieved with a simple architecture like MVC or just plain MVVM.
  • The learning curve is steep.
  • Understanding how to divide the responsibilities into appropriate layers can be tedious if you do not have a clear idea of how each layer works in this architecture.

Android Development with Clean Architecture

I have created the simplest TODO app with a Clean Architecture on the Android platform. You can find the complete code on GitHub.

Note that creating something as simple as the TODO app with Clean Architecture does not cover every aspect of the architecture.

The idea is to understand the basic implementation and work our way to more complex features.

Here is the layering structure used in the approach:

Android app layers in Clean Architecture implementation

The same layering is reflected in the directory structure.

The layering can vary as per the implementation. However, structuring the code base should concentrate on who(layers and elements) depends on whom.

We can add layers as per the complexity and differentiation possible in the code structure. There is no hard rule regarding how many layers should be in the Clean Architecture.

App directory structure
The core module directory structure

Here, we have included the core module as a dependency on the actual app where the core acts as the inner layers (domain, data, use case), and the Android app works as the outermost layers of implementation (framework and presentation).

Domain

The domain layer consists of the core entities that describe the application/module concept. These entities are independent of outer layers and should never mention anything from the outer layers (data, use case, etc.)

Here, we have Task as an entity that defines the basic task and its properties.

Data

This layer defines the interactions with the data. We have TaskDataSource to define the operations on the data. Then we defined a TaskRepository to combine multiple data sources into one repo and access data using the repository.

Here, we only have a single data source. Basically, it is one-to-one mapping to TaskDataSource and TaskRepository methods, which seems redundant at first glance. But the repository pattern can be useful when the application scales and we have data sources from multiple locations, i.e., downloading data from the internet, local database, or data stored in the user files.

The TaskRepository is being used by the use cases discussed below.

Usecase

This layer defines the operations that can be performed on the data and form a use case around it. The presentation layer directly uses these use cases to present or manipulate the data.

Below are the use cases defined to perform various operations on the data:

Use cases

Framework

This layer implements the data sources defined in the Data layer and provides a platform-specific implementation.

For our implementation, we have used the Room database via TaskDataSourceImpl to implement the TaskDataSource.

Presentation

This layer defines the presentation logic in code and how the platform-specific views are used to present the data to the user. Here we have view models which invoke the use cases defined in the use case layer and present them using Android views.

And that’s it!

Wrapping Up

I hope it clarifies Clean Architecture and how you can implement it in Android development.

You can find the complete code of the sample TODO app on GitHub. Raise a PR if you have suggestions on code structure. You are more than welcome to contribute.

Happy coding!

P.S. Special thanks to Prem Patel for the guidance and Sanat Shukla for the support.

References used

--

--