# Clean Architecture

{% embed url="<https://blog.cleancoder.com>" %}

{% embed url="<https://bespoyasov.me/blog/clean-architecture-on-frontend>" %}

## About

It is a model with the objective of decoupling the application independent business rules (or domain), from external resources *(like frameworks, DBs)*.

{% hint style="warning" %}
`Independent Business Rules`, are business rules that are independent of context *(should be followed despite of where are executed)*.

*Ex.: Business Rules that aren't valid only in specific Usecases.*
{% endhint %}

Clean Architecture is `Usecase` driven.

{% hint style="info" %}
In a way every `Clean Architecture` is also `Hexagonal Architecture`, but the opposite is not.

In `Hexagonal Architecture` you don't have the distinction of usecases and entities, you only have the application (hexagon) which is the sum of usecases with entities.
{% endhint %}

{% hint style="warning" %}
The project folder names is completely irrelevant to the `Layers`.

**You can have** `Layers` **without folders separating the files.**
{% endhint %}

## Rules

The inner layers *(high level)* should not know implementations of external layers *(low level)*, which is `SOLID - Dependency Inversion Principle`.

## 4 Layers

<figure><img src="https://3491753774-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLWOeOWWdvzg1GYMe7UTX%2Fuploads%2FOJbAIGTNIcEwAohmnX6W%2FCleanArchitecture.jpg?alt=media&#x26;token=4b1625a3-9088-4213-bb32-11038ada0f6d" alt=""><figcaption></figcaption></figure>

### Entities

They are responsible for abstracting the `Independent Business Rules`, which can be from an object with methods to a group of functions.

<figure><img src="https://3491753774-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLWOeOWWdvzg1GYMe7UTX%2Fuploads%2F2MBLPYOm90CGokTIiltn%2Fimage.png?alt=media&#x26;token=0c304eb8-cf60-4bb7-ad89-6561d7003695" alt=""><figcaption></figcaption></figure>

#### What are Independent Business Rules?

*Ex.:*

* Is `CarPlate` valid?
* What is the distance between two `Coords`?
* How much is the `Ride Fare`?
* How the `Ride Status` change?

#### Domain Objects vs ORM Objects

{% hint style="danger" %}
`Entity` $$\neq$$ `ORM object entity`. (Which is a mere database table representation)
{% endhint %}

<figure><img src="https://3491753774-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLWOeOWWdvzg1GYMe7UTX%2Fuploads%2FoQQntbvyPgl5lHP4Jfkr%2Fimage.png?alt=media&#x26;token=41ed27a7-0e6b-4a38-aee5-8fd2248893fb" alt=""><figcaption></figcaption></figure>

#### Clean Architecture + DDD (Domain Driven Design)

Entities can be broken in Aggregate, Entity, Value Object and Domain Service by using `DDD`.

`Clean Architecture` don't clearly specify what an `Entity` can be as `DDD` does.

{% hint style="success" %}
`DDD` strongly complements `Clean Architecture` `Entity Layer`.
{% endhint %}

#### Anemic Domain

Anemic means that an Object only handles `Properties (State)` OR `Behavior`, but not both.

### Use Cases

They orchestrate the entities and external resources, meaning they will be sort of a bridge between `Entities` and `Interface Adapters`.

Usecases are behaviors offered to the Clients. ***(You application exists because of your exposed Usecases)***

{% hint style="info" %}
Usecase names are related to `Screaming Architecture`, which states to give names related to what it does.
{% endhint %}

{% hint style="danger" %}
Very rarely a `Usecase A` will call another `Usecase B`.

But this still increases coupling in the `Usecase A`, increases time to complete the `Usecase A`.

So, **instead of** calling Usecases inside another Usecase, use `Mediator` Design Pattern to decouple these Usecases by using a `bus/channel` like a `queue`, for communication between them. *(Not necessarilly an external tool like* `RabbitMQ`*)*
{% endhint %}

<figure><img src="https://3491753774-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLWOeOWWdvzg1GYMe7UTX%2Fuploads%2FgeLKSZEdjesbASIHqzh6%2Fimage.png?alt=media&#x26;token=7386c69d-7b7a-4461-ba38-9995e02d29b2" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
In very simple cases, a Usecase can be the same as CRUD operations.

But as complexity increases they will be less alike.
{% endhint %}

### Interface Adapters

These are the bridges between `Usecases` (High level) and `External Resources` (Low level).

<figure><img src="https://3491753774-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLWOeOWWdvzg1GYMe7UTX%2Fuploads%2FK4yojbNGywVk1G1iMN7I%2Fimage.png?alt=media&#x26;token=3494166c-53b4-401f-8992-c4ca782e6a81" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
This is where you:

* Treatment of requests and HTTP responses. *(Dealing with parameters)*
* Access the Database. (All the `SQL` code belongs here)
* Integrate with External APIs.
* Read and Write to files. (Interact with Filesystem)
* Convert data. (Like convert to `CSV`, `PDF`)
  {% endhint %}

### External Interfaces

Here lies the lowest level of abstraction.

Where you actually interact with technology, with the components that connect to the `Database`, that deal with the `HTTP requests`, that interact with the `filesystem` or access `S.O resources`.

The ideia in here is to abstract only some level of the technology used, so that the `Interface Adaptors` won't know for instance if they will connect to a Postgres or MySQL database.

{% code title="DatabaseConnection.ts" %}

```typescript
export default interface DatabaseConnection {
    query(statement: string, params: any): Promise<any>;
    close(): Promise<void>;
}
```

{% endcode %}

{% code title="PgPromiseAdapter.ts" %}

```typescript
export default class PgPromiseAdapter implements DatabaseConnection {
    connection: any;
    
    constructor() {
        this.connection = pgp()('postgres://...');
    }
    
    query(statement: string, params: any): Promise<any> {
        return this.connection?.query(statement, params);
    }
    
    async close(): Promise<void> {
        await this.connection?.$pool.end();
    }
}
```

{% endcode %}

{% hint style="warning" %}
But there is a certain level of restriction for decoupling External Interfaces.

*Ex.: You may not be able to write a contract for the Database connection that works on unsimilar technologies. (Like* `Postgres` *and* `Mongo`*)*
{% endhint %}

<figure><img src="https://3491753774-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLWOeOWWdvzg1GYMe7UTX%2Fuploads%2FSndcxFFf0pa1UeZop2xf%2Fimage.png?alt=media&#x26;token=50d49109-0273-42f8-96ae-0b43997d8042" alt=""><figcaption></figcaption></figure>

#### `Interface Adapter` vs `External Interfaces`

{% hint style="warning" %}
In `Hexagonal Architecture`, there is no difference between `Interface Adapters` and `External Interfaces`, they are the same.
{% endhint %}

An example of mixing Interface Adapters with External Interfaces would be:

Having the code that connects to the Database inside a Repository like this.

{% code title="UserRepositoryDatabase.ts" %}

```typescript
class UserRepository {
    async getUserById(userId: string): Promise<User> {
        const connection = pgp()('postgres://...');
        const user = connection.query('SELECT * FROM user WHERE id = $1', [userId]);
        await connection.$pool.end();
    }
}
```

{% endcode %}

So, there is a certain level of coupling of `Postgres` with our `Interface Adapter` that is called from the `Usecase`.

## Examples of Folder Divisions

```
/src
  ├── /core
    ├── /exceptions
    └── /entities
      └── <entity-name>.ts
  ├── /usecases
    └── <usecase-name>.ts
  ├── /infra
    ├── /repositories
    ├── /gateways
    ├── /http
    └── ...
  └── main.ts
/tests
  ├── /unit
  ├── /integration
  └── /e2e
```
