The basis, structure, and organization of the solution are often referred to as the software design and architecture. We should always put maintainability first when designing a sustainable solution. Maintainability requires a solid foundation and a well-designed architecture for the solution. The solution must adhere to the finest guidelines and design standards.
Robert C. Martin introduced Clean Architecture, a system architecture guideline that is a synthesis of previous architectural proposals.
The concept of "Clean Architecture"
Over the past few years, clean architecture, sometimes referred to as domain-driven design, has seen significant development. Below are a few clean architectural terms that have been used over the years:
- Hexagonal architecture
- Onion architecture
- Domain-driven design (DDD) or domain centric architecture
- Vertical slice architecture
- Clean architecture
All of the above architectures share similar design approaches in that they center the solution structure on the essential business logic and application domain. This architecture decouples the presentation and data access layers from the application's core business logic.
As a result, the main component of this design, which consists of comprehensive business logic and application entities, is meant to be adaptable and flexible enough to deal with evolving technology and interfaces. Additionally, regardless of presentation layers, infrastructures, or databases, the underlying program remains unchanged.
Advantages of a Clean Architecture
- It is easy to maintain.
- It is changeable as per improvements and requirements.
- It is easy to develop. Does not include too much hassle.
- It is easy to deploy.
- It is independent.
- It is testable.
The value Clean Architecture can provide
- The frameworks themselves are contained within the various modules. In the event that we do change our minds, we will only need to make the adjustment in one location. Instead of being bound to a CRUD system, the application makes use of use cases.
- Architecture that shouts its intended purpose is often known as "screaming architecture. Instead of viewing specific technical information, when you look at the structure of the package, you get a sense of what the application is capable of doing.
- Use cases contain all of the company's business logic, making it simple to locate and ensuring that it is not repeated elsewhere.
- Because of the compiler dependencies that are enforced by modules, it is difficult to make a mistake. The application will fail to compile if you try to use a feature that you are not supposed to use.
- Because the wiring of the thing was left until last, it is in a state of constant readiness for use. Or by making use of feature flags so that we can enjoy all the advantages of continuous integration.
- There are several stories in progress, making it possible for multiple couples to work on the same narrative at the same time in order to finish it more quickly.
- A solid monolith with unambiguous use cases that can be subdivided into microservices at a later time, after you've gained greater familiarity with those services.
Basic principles of Clean Architecture
A clean architecture seeks to make solutions flexible by separating the frontend and external frameworks from the solution's core business or application logic and its use cases. In conclusion, we can list the following principles of clean architecture that are beneficial:
- Independent of UI
A well-organized structure will make it easier to make changes to the presentation or user interface layers without affecting other parts of the system. Any front-end framework, console UI, or the web can be used for the UI without affecting the other layers or the rest of the system.
- Database independent
The design must be flexible enough to enable a new database to be implemented without breaking the application's entities and use cases. Part of the answer is to switch the data set to another database like MS SQL, MySQL, Oracle, MongoDB, etc.
- Independent of external agencies, libraries, or drivers
The company's rules must be completely unaffected by any third parties or government bodies. There should be no direct involvement by any external party.
- Framework independent
The fundamental principles of the company or the application itself should work independently of any frameworks or libraries that may be developed in the future. We are able to incorporate the frameworks, but only in the capacity of tools; the solution should not be dependent solely on those.
The user interface (UI), database, web server, and any other external components should not be required for the testing of the core application, business cases, and rules. The design should comply with these tests.
Illustration representation of Clean Architecture
In most cases, Robot Martin (Uncle Bob) will present a fundamental circular illustration that will be used to explore deeper into the clean architecture.
This diagram does a great job of illustrating the key ideas underlying clean architecture. This diagram has two possible interpretations: circular and hemispherical. Either way, the main notion is still clear.
Entities, sometimes referred to as business domain entities, are the inner core of the diagram, as can be seen. It also goes by the name of Enterprise Business Rules.
Use cases, also known as application business rules, are applicable to certain commercial enterprises. These use cases are known as presenters, controllers, or gateways in accordance with the aforementioned concept. Additional external interfaces, such as databases, user interfaces, or the web, are also known as public shells, public surfaces, or public interfaces. The top levels contain all the frameworks and drivers. We can also see that the flow originates from the public shell and proceeds to the inner entities.
The dependencies shift from inner to exterior, or from core to external or public surface, if we look at things from a different angle. The fundamental internal entities and use cases, referred to as the business and application layers, are independent and less likely to change. This circular diagram's layers are interdependent with one another. Because the external layers are more susceptible to change due to new technologies, frameworks, and other factors, the solution architecture has less of an impact on the logic of the core applications. ?
Layers of Clean Architecture
I'll explain the layers of clean architecture in this part. We will once again look at Uncle Bob's illustration's layers.
Another name for these are enterprise business rules. It consists of straightforward domains. To this layer, we add objects (entities or domains) devoid of frameworks and annotations. We provide general logics that are applicable across all domains, such as validations and base entities. Since they are independent, external changes have the least effect on them.
- Use cases
Core business or application logic is written in this layer of pure logic. The term application business rules is often used. We commonly use the terms "services" or "managers" to describe application use cases. Using a domain layer, this layer creates the results. This use case's trigger and intended presentation of the results are unknown. To maintain business logic's independence from the user interface or database, we rely on services. However, we might merely use some libraries as tools.
- Interface adapters
When converting data for storage into external sources like databases, file systems, or third parties, this layer serves as a communicator to ensure that the proper format is used. It can also transform data for use cases or business logic. This layer is sometimes referred to as adapters because it is required to convert data in both directions. At this level, presenters, views, and controllers are components of MVC for GUI or REST APIs. Additionally, it implements the use-case interfaces needed for external components.
- External interfaces
This clean architecture's outermost layer is subject to the most frequent modifications due to new technologies and updates, such as those affecting databases and web front-end frameworks. We display the data to the UI or database in this layer.
- Solution designing
We need to understand that clean architecture is a set of organizational principles. The solution can be designed in a variety of ways depending on the needs of individual modifications, but the fundamental ideas must be upheld and correctly carried out.
- The dependency rule
According to the Dependency Rule, the dependencies that are present in the source code can only point inward.
This implies that something in an inner circle cannot possibly learn anything about something in an outer circle. In other words, the inner circle shouldn't rely on anything that's going on in the outer circle. The dependency rule is illustrated by the black arrows that are displayed in the diagram.
This fundamental principle is what ensures that the design in question will function correctly. In addition to that, this is not easy to grasp.
- Frameworks and drivers
The layer that is most external to the system is often made up of frameworks and tools, like the database and web frameworks. In most cases, you won't be writing a lot of code in this layer other than "glue code," which is used to interface with the following circle inward.
On this layer, all of the individual details are placed. The Internet is only a side note. The database is a minor point to consider. These things are stored outside, where they can inflict the least amount of damage.
Are there only four circles?
Not at all; those are just schematic circles. It's possible that these four won't be enough to solve your problem. There is no hard-and-fast rule that stipulates that you can never have more than these four. The dependency rule, on the other hand, is always applicable. Dependencies on the source code will always lead inward. The degree of abstraction you encounter grows the more you travel inward. The concrete detail at the lowest level is the outermost circle. As you progress deeper into the system, the software will become increasingly abstract and will begin to encapsulate higher-level policies. The outermost ring contains the most specific information.
A demonstration of how we cross circular borders is shown in the diagram's lower right corner. It demonstrates communication between the controllers and presenters and the use cases in the following layer. Take note of the control flow. The execution starts in the controller, progresses through the use case, and finally completes in the presenter. Observe the dependencies in the source code as well. Each of them makes an internal point about the use cases.
Usually, we apply the dependency inversion principle to address this seeming contradiction. For instance, in a language like Java, we would set up interfaces and inheritance connections so that the dependencies in the source code fight the flow of control at precisely the correct places across the border.
The same method is applied to break through all architectural barriers. In order to adhere to the Dependency Rule regardless of which way the flow of control is moving, we use dynamic polymorphism to build source code dependencies that go against it.
The fundamental objective of this "clean" architecture is to build a framework that is versatile and adaptable enough to support new technologies, outside components, and web frontend frameworks. In order to do this, clean architecture offers guiding principles that keep the fundamental entities and business logic separate from presentation layers, infrastructures, databases, and outside agents. You'll get overall ideas about clean architecture from the blog mentioned above.