.NET - Entendendo a Clean Architecture


 Hoje vamos esclarecer os principais conceitos da Clean Architecture.

Eu já apresentei a Clean Architecture em outros artigos e hoje vou esclarecer alguns aspectos desta arquitetura de forma resumida.

Vamos iniciar apresentando a figura ícone da Clean Architecture e a partir dela vamos entender os conceitos relacionados.

A figura apresenta por padrão 4 camadas (isso não é uma exigência):

  1. Entities - Enterprise Business Rules (domínio)
  2. Use Cases - Application Business Rules (casos de uso)
  3. Interface Adapters - Controllers, Gateways, Presenters (comunicação)
  4. Frameworks e Drivers - Devices, DB , UI, Web, External Interfaces (dependências substituíveis)

Com base na figura podemos estruturar uma aplicação na plataforma .NET criando 4 camadas:

  1. Domain -> entities
  2. Application -> use cases
  3. Infrastructure -> interface adapters
  4. WebUI -> frameworks e drivers

E fazer a relação entre as camadas criadas com as camadas proposta pela Clean Architecture mostradas na figura.

Para iniciar a implementação usando a arquitetura proposta pela Clean Architecture não existe uma receita de bolo mas você pode se orientar pelas seguintes etapas:

  1. Divida o código da sua aplicação em camadas;
  2. Defina as abstrações nas camadas mais internas;
  3. Defina as implementações nas camadas externas;
  4. As dependências devem sempre estar de 'fora para dentro' e nunca o contrário;
  5. Realize os testes de 'fora para dentro';

Assim, a aplicação em si pode ser considera como constituída pelas camadas :

Domain - Contém as regras de negócio da sua empresa e onde definimos as Entities que representam o seu modelo de domínio (não o seu banco de dados);

Application (Use Cases) - Contém as regras de negócio da aplicação, onde reside a lógica da aplicação. Aqui são definidos os casos de uso e os repositórios como interfaces e não como implementações; Os casos de uso devem ser implementados em classes independentes para serem utilizadas independente do ambiente de execução e deverão conter suas próprias dependências;

A camada de comunicação entre a aplicação e o mundo exterior é a camada Interface Adapters. Aqui temos as implementações com o mundo exterior que é a camada Frameworks e Drivers. Essa seria a camada também conhecida como Infrastructure.

A camada mais externa refere-se às tecnologias e dependências externas que poderão ser substituídas sem afetar a aplicação.

Dessa forma podemos dividir as responsabilidades definidas na aplicação em : Core, Application e Details.

Assim a camada Use Cases ou Application pode acessar e ter referências à camada Entities ou Domain, e a camada Infra (Frameworks e Drivers) pode ter referência e acessar a camada Uses Cases mas o contrário nunca poderá acontecer.

A camada Use Cases ou Application  contém toda a lógica do aplicativo. Depende da camada Domain, mas não depende de nenhuma outra camada ou projeto. Esta camada define interfaces que são implementadas por camadas externas. Por exemplo, se o aplicativo precisar acessar um serviço de notificação, uma nova interface seria adicionada ao aplicativo e uma implementação seria criada dentro da infraestrutura.

A camada Interface Adapters  refere-se a camada de infraestrutura e contém classes para acessar recursos externos, como sistemas de arquivos, serviços da Web, smtp e assim por diante. Essas classes devem ser baseadas em interfaces definidas na camada Application.

A camada Frameworks e Drivers representa a camada de apresentação e pode ser aplicativo de página única baseado em Angular 10 e ASP.NET Core 5. Essa camada depende das camadas de Aplicativo e Infraestrutura, no entanto, a dependência da Infraestrutura serve apenas para oferecer suporte à injeção de dependência. Portanto, apenas a classe Startup.cs deve fazer referência a Infraestrutura.

A comunicação entre as camadas é feita usando interfaces. Assim a camada Domain se comunica com a camada Application definindo interfaces que serão implementadas naquela camada, e, o mesmo vale para as demais camadas. Assim não temos uma dependência direta entre as camadas mais internas e as camadas externas respeitando a regra de dependência.

A regra de dependência talvez seja a mais importante da Clean Architecture, e, a essência da regra de dependência reside no controle do fluxo de dependências do aplicativo. Embora qualquer uma das camadas em uma arquitetura limpa possa encapsular uma dependência, essas dependências podem apenas apontar para dentro, já que as camadas internas são projetadas para não ter nenhum conhecimento das camadas externas.

Por exemplo, embora a camada dos adaptadores possa reter uma dependência com um componente da camada do aplicativo, a camada do aplicativo não pode ser dependente de nada dentro da camada do adaptador pois isso violaria a regra de dependência.

Outro princípio importante usado na Clean Architecture é o princípio de abstração que afirma que as regras de negócios e camadas de aplicativos devem conter regras de negócios/lógica de negócios, com o círculo mais interno sendo o mais abstrato.

Enquanto isso, as camadas do adaptador e da infraestrutura (camadas mais externas) devem conter detalhes de implementação, com o círculo mais externo sendo o mais concreto.

E estamos conversados.

Não furtareis, nem mentireis, nem usareis de falsidade cada um com o seu próximo;
Levítico 19:11

Referências:


José Carlos Macoratti