Clean Architecture: some architectural patterns explained
Tags: architecture, cleancode, java
Published: 2022-10-10 23:12:49

## Motivation

Would you ever asked yourself why we are creating packages in our projects, or what are possible ways to organize your classes and modules, is this packing way came by luck or there is a science behind it we will discuss all these questions here.

## Designing good software structure

As software grows maintaining and organizing it became more difficult, and in order to keep the software more organized you have to design its structure in good way.
Designing good software structure requires some characteristics like **intention revealing**, **components decoupling** and ease of **component replacement**

## Intention Revealing

By this we mean that when I look at the software components I can get some knowledge about what this software does.

## Components Decouple

Here we should reduce coupling between components which offers to us ease of component replacement without a lot of problems.

In order to achieve these goals there are multiple architectural styles you can go with, and these architectural styles are meant by how you should organize your **classes**, **packages** and **modules**.

**Package by layer**

This is most popular and easy way to organize and style your software, in this style you have packages like **controller, service, repository, model/entity** or any components that represents layers like **Presentation layer**, **Business Logic layer** and **Data Access Layer**. Layers or components are built on top of each other and each layer is allowed to use direct below layer only as below image


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cwfr4cr0q30elgr50d15.png)

and this is represented in your project as below


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ha2tu80ibvuz5pw259pa.png)

In order to achieve components decoupling it's common practice to start by using interfaces between layers like (JPA repositories) between **Data Access Layer** and **Service/Business Logic** layer. and interfaces between **Service/Business Logic** layer and **Controller/Presentation** Layer so you can easily swap between components and implementation.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/11z6298dql1syc8cq7ob.png)

This style is easy to implement, easy to understand and also easy to follow, but in another hand this style has some issues like it violates **intention revealing**, you can not get what is software does by just looking to its structure, you have to go deep dive with code to understand it, also there is another problem it's easy to follow but it's also easy to break, with deadlines and lack of experience you can bypass layers, and maybe some developers use Data Access Layer(Repositories) in Presentation Layer (Controllers) directly and this violate the entire style as below.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6ihc0ydz21wtrkrn77h1.png)

## Package by feature

With this style you are repeating **Presentation, Business logic and Data access** layers with each feature you have, and you follow same rules that you have in **package by layer** style as below.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bzygl51kk9zgwqku0osp.png)

and this is represented in your project as below


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bidt78us05l6ttigll0t.png)

By using this style your are gaining **intention revealing** for your software, by just looking to project structure you can gain good knowledge about what this software does, you also gain some **focus** when you are try to look at specific feature, now you know where exactly you should go and don't bother your self about other features, you may also suffer from bypassing layers but it's less than in Layered Architecture.

## Package by component

In this style you are creating separate units of deployments like jar files in java or separate projects and combine this style with one of previous styles in each of these components/projects as below.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3i0f0ceglwvr3fbicfcq.png)

By using this style you are gaining flexibility of deploying features/modules as you wish, you can add or remove features and modules when you are delivering the software to the client and give your client **flexibility** to choose what modules he needs only.

## Hexagonal style

This style is elegant and makes you focus on core business logic and defer implementation to another components that provides you implementation details, and most benefit from this style comes when you have multiple implantation providers.
As below image describes you are just writing the main core business logic and let other parts to complete the component or picture with specific implementation, then you can switch between them in easy way.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kh3nvsaldge3phangm5m.png)

**Ports and Adapters**

Let's take an example to explain how this style can be achieved, let's say you have core functionality in your system that the manager can browse employees data after some manipulation done upon them, but also you have multiple clients and each client have its own data source, someone uses relational database some others uses excel sheets and so on.

So these are steps

you write generic code without pay attention to details and this can be done by depending on interfaces, these interfaces is called **Ports** (you are exposing them to defer implementation to another modules) and this will be the core functionality as below


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/up6ae8ze0hk5fy9vj0l6.png)

Off course this code will not work with current state it is lacking of implementation of how we will get the employees, and to complete the functionality you need the **adapters**.

The **Adapters** representing the implantation of your **Ports** that exposed in your core logic so as per our example these are our adapters.

**Relational DB adapter**


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b3soslr15kmsbfr3r4mn.png)

**Excel sheet adapter**


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/22t1brs0sqvtw817lipx.png)

And now with any **Dependency Injection** provider you are able to let your client to choose which adapter suits him and combine it with your logic then deliver your system in easy beasy way.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dequnfnkx3aew8l9mjsj.png)

## Resources

- [Clean Architecture](https://www.amazon.com/dp/0134494164/ref=tsm_1_fb_lk)

- [Clean Architecture + CQRS](https://youtu.be/NzcZcim9tp8)

- [Packaging by layer vs Packaging by feature](https://www.amido.com/blog/packaging-by-layer-versus-packaging-by-feature)

IF YOU LIKED THE POST, THEN YOU CAN BUY ME A COFFEE, THANKS IN ADVANCE.

<a href="https://www.buymeacoffee.com/samehmuh95" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174"></a>