Decide which architecture to use - Clean architecture topic
This is a pretty wide topic and because I don’t want to exaggerate and give a lot of information at once, about different types of architecture, that is hard to understand and digest, this will be a subject split into 2, 3, or maybe more parts, depending on how big every topic will be.
In this series of articles, we will look at what is architecture and how to make the distinction between different types of architecture, or as I like to call them, internal architecture and structural architecture.
We will also take a look at some of the most popular architectures and which one should we consider for the application.
Please keep in mind that no architecture is a silver bullet, nothing is perfect. Some of them might add extra complexity that is not needed.
Also, the architectures here are more of a guideline, you can add extra stuff or remove things that don’t fit in your project.
Internal architecture
This type of architecture represents the inside of our project and it is responsible for how our solution or project is organized.
Some examples of this architecture are Clean architecture, N-Layer architecture, MVC (model-view-controller) architecture, etc.
Structural architecture
This architecture represents the outside of our project and how our pieces communicate together.
This can be Microservices, Monoliths (doesn’t matter if we talk about modular or non-modular ones), Event-driven architecture, DDD (Domain driven design) architecture, Service-oriented architecture, etc.
Why the distinction?
I wanted to make this distinction because it will be easier this way to understand and avoid confusion when you build an application. It is also important to know that internal-type architecture can be combined with structural-type architecture.
How? Well, for example, we can have a monolith architecture paired with clean architecture.
We can have microservices architecture and each microservice can contain its own internal type of architecture.
1. Clean architecture
The most popular type of internal architecture is clean architecture paired with CQRS (Command and Query Responsibility Segregation) pattern and Mediator pattern (usually used through the MediatR library).
I think most of you have already seen the onion-type architecture. Below we have a representation of that together with the dependencies of each layer.
Domain Layer
This usually contains all the entities and the business logic related to those. This layer should be kept as simple as possible.
Application Layer
Contains application-specific business rules.
Here we have a big list of things that we can add, and these are some of them:
Behaviours
Exceptions
Mappings
Models and/or DTOs
Commands and Commands handlers
Queries and Queries handlers
EventHandlers
Interfaces
etc.
Infrastructure Layer
In this layer, we add everything that our application needs in order to use external services. Examples:
Database
Azure services
Third-party services like GitHub
etc.
Everything that makes a request outside of our application should be here.
Web UI / API
This should contain the parts that communicate with the client and everything related to them:
Controllers
Views
ViewModels
etc.
Pros of clean architecture
Separation of concerns. The application contains multiple layers, each responsible for a specific aspect.
Testability. The application is decoupled which makes it easier to add unit tests and integration tests.
Loose coupling (Swap out of the implementation). It is easy to swap out a service, for example, if needed it is easy to swap a database from MSSQL to PostgreSQL.
Maintainability.
Cons of clean architecture
Complexity. A high learning curve to understand everything.
Structure checks. It can become a mess without proper restrictions. For example, someone can reference the domain in infrastructure if they don’t know what they are doing.
Ambiguity. Sometimes it can be hard to decide where something should be added, whether it should be in the Application or API layer.
Easy to overengineer.
When to use it?
We want to use clean architecture in a few scenarios:
When we build the application around our domain
When we have complex applications with complex business logic, the structure of this architecture helps us keep it tidy and clean
When we have to build critical projects with high testability
When we know we might need to swap out services in the future
Closing thoughts
Clean architecture is very versatile, it can also be very complex, and it can be misused very easily, but we also gain a lot if we implement it right.
I also suggest you take a look at the template for this architecture. It might help you build a better image of everything that each layer is doing.
You can find the templates in the following link.