An introduction to Clean Architecture
Learn what is Clean Architecture and how it can significantly benefit your software development projects.
Today’s market is fierce, and companies need to continually work on their digital products and services to stay relevant, keep up with users’ increasing demands, and reach wider audiences.
In this context, software architecture plays a fundamental role. And one particular methodology has been gaining popularity in the past years: we’re talking about Clean Architecture.
Adopting a Clean Architecture mindset in large, high-risk projects like the development of a new app allows your team to create a more cost-efficient product that is easy to develop, maintain, and deploy.
In this article, we are going to give you an overview of what is Clean Architecture and what are its main characteristics and benefits.
So, what is Clean Architecture?
Clean architecture is a software design philosophy introduced by Robert C. Martin in 2017 in a book by the same name. It essentially refers to the organization of code into separate components or modules and how these elements relate to each other.
Clean Architecture’s primary goal is to provide a methodology to develop code that performs better, has few dependencies, and is simple to understand and maintain, reducing costs and maximizing programmer productivity.
In recent years, Clean Architecture has become fairly popular and many software development teams are adopting it worldwide. One of the main reasons is that it helps design applications with very low coupling and high cohesion. That way, applications become more testable and flexible to change as the project grows.
Main characteristics of a Clean Architecture
The most common depiction of Clean Architecture is a diagram consisting of concentric circular layers, very reminiscent of The Onion Architecture. The inner layers represent high-level, abstract policies, while the outer layers are the technical implementation details.
The software architecture of an app defines where the system performs its core functionality and how it interacts with things like the database and the user interface.
At the center of the circle, we have the Domain or business rules. Business rules are the reason a software system exists. They are the core functionality of an application.
Ideally, the code that represents the business rules should be the heart of the system, with lesser concerns plugged into them. The business rules should be the most independent and immutable code in the system.
The outer you go on the circle, the elements become less critical and more prone to change. In this sense, the presentation and data are less important since they are implementations that can eventually be replaced.
The dependency rule
The main rule of Clean Architecture is that code dependencies can only come from the outer levels inward, and the inner layers should have no knowledge of the functions on the outer layers.
By making sure your business rules and domain logic are entirely devoid of any external dependencies, you achieve what is called a clean separation of concerns. You create a boundary ensuring that the core of your app doesn’t know anything about the infrastructure.
That means the UI and the database depend on the business rules, but the business rules don’t depend on the UI or the database. It doesn’t matter if your product is a web interface, a desktop app, or a mobile app. It doesn’t matter if the data is stored using SQL, NoSQL, or the cloud. The Domain doesn’t care.
The secret to building a scalable product that is easy to maintain is separating the files or classes into components that can change independently from other modules. This is known as plugin architecture.
In software development, the classic clean architecture is divided in the following layers:
– Entities: Entities are the set of related business rules that are critical for an application to function. They are entirely independent of any other element within the architecture. When a Clean Architecture is employed, the Entities don’t know anything about the other layers.
– Use cases: Use cases represent the actions a user can perform in the application. They are a description of the way that an automated system should behave. Use cases interact with and depend on the Entities, but they know nothing about the outer layers. Use cases do not determine how the system appears to the user. Instead, they describe the rules that govern the interaction between the users and the Entities.
– Interface adapters. Interface adapters provide a bridge between the outside world and the Use cases and Entities. They are the translators between the Domain and the Infrastructure. Models, views, presenters, and repository implementations all belong to this layer.
– Infrastructure. Infrastructure represents the external agents. This layer is where all the I/O components go: the UI, database, frameworks, and devices. It’s the most volatile layer because the elements contained here are the more likely to change.
The SOLID Principles
“A good software system begins with clean code“, says Robert C. Martin in his book Clean Architecture. But, what does he mean? Essentially, clean code is code that is easy to understand and easy to change over time.
In this sense, the SOLID principles tell us how to arrange our functions and how classes should be interrelated to each other. They provide clear, actionable guidelines for writing clean, maintainable code.
The goal of SOLID principles is to create software structures that are easy to understand and modify. These five principles have been around for the past 40 years in the software development industry, but they became distinctly popular in the early 2000s.
Single Responsibility Principle (SRP)
The Single Responsibility Principle establishes that a class should only have one reason to change.
According to Robert C. Martin, software systems change to satisfy users or stakeholders. A module should be responsible to one, and only one, user or stakeholder. If the same class responds to requirements from different actors, then you should divide it into two separate modules.
Open / Closed Principle (OCP)
The Open / Closed Principle determines that a software artifact should always be open for extension, but closed for modification. This means software systems have to be easy to change, but they must be designed in a way that changes occur by adding new code, rather than changing the existing one.
Good software architecture should reduce the amount of changed code to the barest minimum—ideally, zero.
Liskov Substitution Principle (LSP)
The Liskov Substitution Principle establishes that lower-level classes should be substituted without affecting the behavior of higher-level components. If we apply this principle on the architectural level, we should be able to replace, for example, MySQL with MongoDB without changing the domain logic.
Interface Segregation Principle (ISP)
The Interface Segregation Principle states that no client should be forced to depend on methods it does not use. As Robert C. Martin puts it: “depending on something that carries baggage that you don’t need can cause you troubles that you don’t expect.”
Dependency Inversion Principle (DIP)
The Dependency Inversion Principle establishes that code that implements high-level policy should never depend on code that implements low-level details.
This means the direction of dependency should always be inverted. That way, stable software architectures avoid depending on volatile concretions and favor the use of stable abstract interfaces.
In addition to the SOLID principles, there are other development axioms that play a significant role in developing a Clean Architecture, such as the Component Principles. For more information on this subject, we recommend you to read Robert C. Martin’s book:
Benefits of Clean Architecture
Adopting a Clean Architecture mindset in a software development project can bring great benefits and advantages in terms of work times, costs, and productivity.
Here are some of the most significant benefits of Clean Architecture:
- Clean Architecture enables a software system to be easily deployed with a single action, reducing costs and work times.
- Clean Architecture allows systems to communicate operational needs efficiently, making them readily apparent to developers. This simplifies the understanding of the code and, therefore, aids in development and maintenance.
- Maintenance is usually the most costly aspect of a software development project. Adding new features and dealing with bugs consume a vast amount of resources. On top of that, there’s always a latent risk of inadvertently creating new issues while digging through the software to fix a defect. By separating the system into components and isolating those components through stable interfaces, it is possible to significantly reduce the risk of inadvertent breakage.
- Clean architecture also makes code much more testable. It’s difficult to test code when there are lots of dependencies. But when you have a plugin architecture, that’s no longer a problem.
- Clean Architecture allows Use cases to be more visible and easier to understand. Business rules are not scattered all over the place, so debugging is way easier.
- Because the Use Cases are decoupled from the UI or infrastructure, it’s easy to do things like switch the database or web framework or even port to an entirely new platform.
Why we use Clean Architecture at Bixlabs
One of our primary goals at Bixlabs is to build user-friendly products that are able to scale and grow as businesses expand their frontiers. In this sense, Clean Architecture allows us to develop software that is able to adapt with ease to the constantly changing market requirements.
Being able to add new features or applying substantial changes to a product without having to face significant technical difficulties gives us the flexibility any app needs to achieve product/market fit.
We believe that the more tools developers have at their disposal, the more options they will have when it comes to making critical decisions. Clean Architecture is a tool that allows us to write better code, and develop stable, scalable, maintainable applications.
At Bixlabs, we have more than six years helping top-tier startups to build their digital products. We have a multidisciplinary team of software engineers trained in the latest technologies and eager to work in innovative projects.