Understanding Clean Architecture in Android Development

Kayvan Kaseb
Software Development
10 min readFeb 21, 2022
The picture is provided by Unsplash

Basically, developing high-quality code for high-complexity Android apps requires considerable effort and experience. Moreover, there has always been a problematic issue on which architectural pattern should be used in Android development. Nowadays, there have been debates about building your Android apps in a clean way. To address these challenges, Robert C. Martin, also known as Uncle Bob, came up with the Clean Architecture concept. This article aims to discuss some concepts, rules, and best-practices in using Clean Architecture approach in Android development.

Introduction and Overview

As you know, developing high-quality code for high-complexity Android apps requires considerable effort and experience. An application should not only meet the customer’s requirements, but also must be flexible, testable, and maintainable. In the beginning of software development, software systems really did not have the same concept of a Graphical User Interface (GUI) like we have today. Then, in the 80s and 90s, more visual interfaces began to become commonplace. Therefore, it did an advanced host of problems for software developers. Some questions have been created as follows: How do you manage dynamic user input? How do you keep the view state in sync with the underlying application? How can you best separate your presentation logic from your domain logic?

Basically, Software Architecture refers to the fundamental structures of a software system and the discipline of creating such structures and systems. This means Software Architecture serves as a blueprint for a system. It offers an abstraction to handle the system complexity, and establishes a communication and coordination mechanism among software components and elements. Software Architecture is about building essential structural choices, which are costly to change once implemented.

Additionally, there has always been a controversial issue on which architectural pattern should be used in Android development. Recently, there have been debates about building your apps in a clean way. To address these challenges, Robert C. Martin, also known as Uncle Bob, came up with the Clean Architecture concept, has written a book, particularly on this major. Because the Clean Architecture can be used in any app and platform, not just only Android, it is very informative to understand the idea behind it, and why it would be a proper solution for most technical issues we find as software developers. Initially, Clean Architecture is a software design philosophy that separates the elements of a design into ring levels. The fundamental rule of clean architecture is that code dependencies can only come from the outer levels inward. In other words, code on the inner layers can have no knowledge of functions on the outer layers. The variables, functions and classes (entities) that exist in the outer layers can not be indicated in the more inward levels. In addition, it is recommended that data formats stay separate among levels.

The Importance of Clean Architecture

Obviously, all architectures have one common goal: handling the complexity of your software. You do not require to use it on a smaller project; however, it becomes a lifesaver on large scale ones. Now, the most important question is that how does Clean Architecture address our issues?

The picture is provided by CleanCoder blog

Nowadays, there have been different range of ideas relating to the architecture of systems as follows:

  1. Hexagonal Architecture (a.k.a. Ports and Adapters) by Alistair Cockburn and adopted by Steve Freeman, and Nat Pryce in their wonderful book Growing Object Oriented Software

2. Onion Architecture by Jeffrey Palermo

3. Screaming Architecture from a blog of mine last year

4. DCI from James Coplien, and Trygve Reenskaug.

5. BCE by Ivar Jacobson from his book Object Oriented Software Engineering: A Use-Case Driven Approach

Uncle Bob has mentioned that even though these ideas and architectures all vary in their details, they are very similar in their goals. In fact, they all have the same objective, which is the separation of concerns as the most important one. They all achieve this separation by splitting the software into different layers. Each has at least one layer for business rules, and another for interfaces. The above diagram is an effort at combining all these system architectures into a single actionable unit.

As it was mentioned, since Android apps grow in size, it is extremely significant to define an architecture that allows the app to scale, improves the app’s robustness, and makes the app easier to test. An Android app architecture defines the boundaries among various elements of the app and the responsibilities each part should have. To meet the needs mentioned above, you should design your app architecture to follow some specific principles, goals, and best-practices as follows:

  1. Separation of concerns: This is a design principle for separating a computer program into distinct sections. This means each section addresses a separate concern. A concern is a set of information, which affects the code of a computer program. For example, Google has recommended three main layers in this way for Android development: 1. UI 2. Domain 3. Data.
The picture is provided by Google documents

In other words, It is a common mistake to write all your code in an Activity or a Fragment. These UI-based classes should just only consist of logic that manages UI and OS interactions. By maintaining these classes as lean as possible, you can avoid a number problems associated to the component lifecycle, and enhance the testability of these classes effectively.

2. State synchronization: The idea is that you have three different states of the data, which exist in your application at any time: 1. Screen state 2. Session state 3. Server state. Therefore, if you are planning to have multiple layers in your Android app, you have to make sure that this would be synchronized across each one.

3. Dependency Rule: This idea defines that each circle in the architecture can depend only on the nearest inward circle to make the Software Architecture as clean as possible.

4. Abstraction Principle: The center circle is the most abstract, and the outer circle is the most concrete. In short, that inner circles should include business logic, and outer circles should consist of implementation details.

5. Testability: Initially, testing your app is an inseparable part of the software development process, specially when it comes to Clean Architecture because one of the primary goals of separated components is that it can make easier to test each component. In other words, by running tests on your Android application consistently, you can be able to verify your app’s correctness, functional behavior, and usability before the releasing process.

6. Simplicity of design: It means eliminating unnecessary detail and complexity can lead to elegance in design, which plays a key role in developing high-quality application.

In software engineering, coupling is the degree of interdependence between software modules; a measure of how closely connected two routines or modules are; the strength of the relationships between modules.

Finally, there are some additional advantages by using Clean Architecture approach in coding, such as getting decoupled and having easier process to reuse the codes. Also, code comprehension is much easier for other developers that are planning to work on your project in future.

Using SOLID Principles

In addition to those rules and best-practices that mentioned before, there are five design principles in Object-Oriented software development intended to make software design more understandable, flexible and maintainable.

These five principles are described by Robert C. Martin. SOLID principles are briefly as follows:

  • SSingle Responsibility Principle (known as SRP): if our class does more than one responsibility, we should split the functionalities and responsibilities in various classes.
  • OOpen/Closed Principle: an entity can allow its behavior to be extended without modifying its source code.
  • LLiskov’s Substitution Principle: It means that a sub-class should override the methods from a parent class, which does not break the functionality of the parent class.
  • IInterface Segregation Principle: This principle is related to the fact that a lot of specific interfaces are better than one general-purpose interface.
  • DDependency Inversion Principle: Classes should depend on abstraction, but not on concretion.

Clean Architecture and Layers

Now, the question is that how many layers in Clean Architecture approach can be defined. In fact, the circles are schematic. Thus, there is no rule that indicates you must always have just exact layers as Uncle Bob says. However, some rules always applies, like the Dependency Rule. Source code dependencies always point inwards. As you move inwards the level of abstraction grows. The outermost circle is low level concrete detail. As you move inwards the software increases more abstract, and encapsulates higher level of policies. So, the inner most circle is the most general. For instance, Uncle Bob has defined Clean Architecture approach into four layers briefly as follows:

  1. Entities: It encapsulates Enterprise wide business rules. An entity can be an object with methods, or it can be a set of data structures and functions. They encapsulate the most common and high-level rules. Operational change to any specific application should not affect the entity layer.
  2. Use Cases: The software in this layer includes application specific business rules. It encapsulates and implements all of the use cases of the system. These use cases orchestrate the flow of data to and from the entities. In short, this layer is isolated from some concerns, such as database and UI.

3. Interface Adapters: Uncle Bob believes that this layer can consist of the MVC architecture of a GUI if it is used. The Presenters, Views, and Controllers all belong in this part. The models are likely just data structures that are passed from the controllers to the use cases, and then back from the use cases to the presenters and views.

4. Frameworks and Drivers: In general, the outermost layer contains frameworks and tools, such as the Database and the Web Framework. You don not write much code in this layer.

Furthermore, as it was mentioned, the idea is that you can be able to change the number of layers as you need. So, for example, you can use five layers in your Android app architecture simply as follows:

  1. Presentation: A layer that interacts with the UI.

2. Use cases (also called interactors): Defines actions the user can trigger.

3. Domain: Includes the business logic of the app.

4. Data: Abstract definition of all the data sources.

5. Framework: Implements interaction with the Android SDK and supports concrete implementations for the data layer.

However, the project structure in Android plays an important role in implementing your architecture in practice. For example, you can split your Android project into two modules: 1. app module. 2. a core module, which will hold all your code that does not depend on Android SDK at all.

The picture is provided by Clean Architecture Tutorial for Android

Using MVVM with Clean Architecture Approach

Initially, in the above five layers approach for Clean Architecture, you can be able to use MVVM design pattern in your Android application due to supporting by Android Jetpack. However, you can use other design patterns in this layer as you like, such as MVI and MVP.

Model — View — ViewModel (MVVM) is the industry-recognized software design pattern, which controls and eliminates all drawbacks of MVP and MVC design patterns in Android development. MVVM provides separating the data presentation logic (Views or UI) from the core business logic part of the application efficiently. The different parts of MVVM can be explained briefly as follows:

The picture is provided by GeeksforGeeks
  1. Model: This layer is responsible for the abstraction of the data sources. This means Model and ViewModel must work together to obtain and save the data.

2. View: The goal of this layer is to inform the ViewModel about the user’s interaction. This layer observes the ViewModel and does not include any kind of application logic.

3. ViewModel: It exposes those data streams that are linked to the View. Also, it servers as a connection between the Model and the View.

However, if you use Clean Architecture in your Android app appropriately, instead of relying on Models, you will communicate with Interactors from the Use Case layer.

Dependency Injection and Clean Architecture

As a matter of fact, Dependency Injection is a technique that one object provides the dependencies of another object. A “dependency” is an object that could be used as a service. The “injection” refers to the passing of a dependency (a service) into the object (a client) that will use it. Dependency Injection in build upon the concept of Inversion of Control, which indicates a class should get its dependencies from outside. In simple words, no class should instantiate another class; however, should get the instances from a configuration class. It is the fifth principle of SOLID, which states a class should depend on abstraction and not upon concretions (hard-coded). In Clean Architecture approach, if you require an effective way to support the data sources to the data layer, you should typically accomplish this task using Dependency Injection. So, to perform this task properly, you can utilize some frameworks, such as Dagger 2 and Hilt. Hilt is a Dependency Injection library developed by Google that helps you get the most out of DI best practices by performing the hard work, and generating all the boilerplates you would need to write.

Some general recommendations in Android app architecture

As you know, even though there are a number of ways to implement an Android app architecture based on Clean Architecture approach, Google has suggested some general recommendations for having high-quality Android app architecture. For instance:

  1. You should not store data in entry points components, such as Activity and Fragment.
  2. Your app component should be the just only class, which links to Android framework SDK APIs, such as Context and Toast.
  3. You should focus your time and energy on what makes your Android app unique. Moreover, you should use Jetpack libraries and other recommended libraries to manage the repetitive boilerplate codes.
  4. You should consider how to make each part of your app testable in isolation.

In conclusion

Clean Architecture is a software design philosophy that separates the components of a design into various ring levels. Since the Clean Architecture can be used in any app and platform, not just only Android, it is very informative to understand the idea behind it. This essay considered some best -practices, concepts, and ideas in Clean Architecture for Android developers.

--

--

Kayvan Kaseb
Software Development

Senior Android Developer, Technical Writer, Researcher, Artist, Founder of PURE SOFTWARE YAZILIM LİMİTED ŞİRKETİ https://www.linkedin.com/in/kayvan-kaseb