Clean Architecture - Uma introdução revisitada
Hoje vamos revisitar os conceitos relacionados à Clean Architecture. |
Antes de apresentar os conceitos da Clean Architecture vamos rever o conceito de Arquitetura em Camadas.
Vamos iniciar com arquitetura clássica em N-Camadas ou N-Tier. Isso já existe há mais de 20 anos e ainda é muito usada atualmente.
A vertente mais usada da arquitetura em Camadas ou N-Tier é a arquitetura implementada em 3 camadas:
Cada camada só tem permissão para se comunicar com a próxima camada inferior (ou seja, a IU não pode se comunicar diretamente com os Dados).
Superficialmente, essa limitação pode parecer uma boa ideia, mas, na implementação, significa um conjunto diferente de modelos para cada camada, o que resulta em muito código de mapeamento. Esse problema é ampliado quanto mais camadas você adiciona.
A seguir veremos cada uma das camadas e seu componentes:
Esta estrutura é típica de aplicações ASP.NET Core MVC ou Web API.
É nesta camada que esta a essência das aplicações que usam a arquitetura em Camadas ou N-Tier.
A camada de acesso aos dados define a lógica para acessar os dados na aplicação.
Agora vamos apresentar os conceitos da Clean Architecture comparando com a arquitetura em camadas.
Apresentando a Arquitetura Limpa
Esta arquitetura teve muitos nomes ao longo dos anos.
Onion Architecture, Hexagonal Archecture, Screaming Architecture e
outros. Essa abordagem não é nova, mas também não é tão comum quanto deveria
ser.
Então, em comparação com a arquitetura em camadas ou
N-Tier, o que é Arquitetura Limpa e como ela é diferente?
Vamos iniciar com uma figura que representa a Clean Architecture:
A primeira coisa a notar aqui é a direção das dependências.
Todas as dependências fluem para as camadas mais internas. Camadas externas podem se comunicar com QUALQUER camada interna (compare com N-Tier, onde cada camada só pode se comunicar com a camada abaixo).
Isso segue o
Princípio de Inversão de Dependência, o que
significa que as dependências são injetadas em vez de serem criadas
explicitamente. Outro nome para isso é o Princípio de
Hollywood: não nos chame, nós ligaremos para você.
As camadas Application e
Domain são considerados o "núcleo" do aplicativo. A camada
Application depende da Domain,
mas o domínio não depende de nada.
Quando o aplicativo precisa de funcionalidade da infraestrutura (por exemplo,
acesso ao banco de dados), o aplicativo definirá suas próprias interfaces
que a infraestrutura implementará.
Esse desacoplamento é enorme e é um dos principais benefícios dessa abordagem. Isso não apenas permite testes de unidade mais fáceis, mas também significa que ela ignora a persistência.
Ao consultar
dados, o armazenamento de dados subjacente pode ser um banco de dados, um
serviço da web ou até mesmo um arquivo simples. O aplicativo não se importa e
não precisa saber. Como os detalhes de implementação estão fora do núcleo, isso
nos permite focar na lógica de negócios e evita a poluição com detalhes menos
importantes.
Ela também fornece flexibilidade, pois hoje os dados podem vir de uma fonte de
dados, mas no futuro podem precisar vir de uma fonte de dados diferente. Devido
ao acoplamento fraco, apenas a camada de infraestrutura precisará ser alterada
para oferecer suporte a isso.
Assim destacamos as seguintes características da Clean Architecture:
O objetivo disso é tornar mais fácil para os desenvolvedores fazerem as coisas certas e tornar difícil para eles fazerem as coisas erradas.
A seguir vamos apresentar as camadas e suas particularidades.
Entities
Value Objects
Aggregates (DDD)
Enumerations
A camada
Domain é o coração de seu aplicativo e responsável
por seus modelos principais. Os modelos devem ignorar a persistência e
encapsular a lógica sempre que possível. Queremos evitar acabar com modelos
anêmicos (ou seja, modelos que são apenas coleções de propriedades).
A camada Domain pode ser incluída na camada
Application, mas se você estiver usando uma
estrutura de entidade semelhante a ORM, a Camada de Infraestrutura precisará
fazer referência aos modelos de domínio, caso em que é melhor dividir em uma
camada separada.
As anotações de dados devem ser deixadas de fora dos modelos de domínio. Isso
deve ser adicionado na camada de infraestrutura usando sintaxe fluente. Se você
está acostumado a usar as anotações de dados para sua validação, eu recomendo
usar a Fluent Validation na Camada de Aplicação,
que fornece mais capacidade para eventos do que as anotações.
Application Interfaces
View Models / DTOs
Mappers
Application Exceptions
Validation
Logic
Commands / Queries (CQRS)
Este é a
Application do seu Domain
usado para implementar os casos de uso para o seu negócio. Isso fornece o
mapeamento de seus modelos de domínio para um ou mais modelos de visualização ou
DTOs.
A validação também vai para essa camada. Pode-se argumentar que a validação vai
para o domínio, mas existe o risco de que os erros levantados possam fazer
referência a campos não presentes no DTO / Modelo de
Visualização, o que causaria confusão. Assim, é melhor ter validação
potencialmente duplicada do que validar um objeto que não foi passado para o
comando / consulta.
Considere usar comandos e consultas CQRS para lidar com todas as solicitações de
aplicativos. O MediatR pode ser usado para
facilitar isso e adicionar comportamento adicional como registro, armazenamento
em cache, validação automática e monitoramento de desempenho para cada
solicitação. Se você optar por não usar o CQRS, poderá trocá-lo pelo uso de
serviços.
A Camada de Aplicativo SOMENTE faz referência à Camada de Domínio. Ele não sabe
nada de bancos de dados, serviços da web, etc. No entanto, define interfaces
(por exemplo, IContatoRepository, IContatoService, IMessageBus), que são
implementadas pela camada de infraestrutura.
Database
Web services
Files
Message Bus
Logging
Configuration
A camada de
infraestrutura implementará interfaces da camada de aplicativo para fornecer
funcionalidade para acessar sistemas externos. Eles serão conectados pelo
contêiner IoC, geralmente na Camada de
Apresentação.
A camada de apresentação geralmente terá uma referência à camada de
infraestrutura, mas apenas para registrar as dependências com o
contêiner IoC.
MVC Controllers
Web API Controllers
Swagger / NSwag
Authentication / Authorisation
A camada de apresentação é o ponto de entrada para o sistema do ponto de vista do usuário. Suas principais preocupações são o roteamento de solicitações para a camada de aplicativo e o registro de todas as dependências no contêiner IoC. Se você estiver usando ASP.NET, as ações nos controladores devem ser muito finas e, na maioria das vezes, simplesmente passar a solicitação ou o comando para MediatR.
Variações
As camadas
descritas até agora constituem a abordagem básica da Arquitetura Limpa. Você
pode precisar de mais camadas, dependendo do seu aplicativo.
Se você não estiver usando um ORM, poderá combinar as camadas de domínio e de
aplicativo para simplificar. Você pode querer dividir a infraestrutura em outros
projetos (por exemplo, Persistência). Essa abordagem funciona bem com o
Domain-Driven Design, mas funciona igualmente bem
sem ele.
O CQRS é a abordagem recomendada para o ponto de entrada na camada de
aplicativo. No entanto, você também pode usar serviços típicos se não se sentir
confortável com isso.
Conclusão
Aplicar as diretrizes da Clean Architecture resulta em uma arquitetura e design que é:
Independente de Frameworks - O núcleo da
aplicação ou Core que inclui as camadas Domain e
Application, não deve depender de frameworks externos, como Entity
Framework;
Testável - A lógica dentro do Core pode ser testada
independentemente de qualquer coisa externa, como interface do usuário, bancos
de dados, servidores. Sem dependências externas, os testes são muito simples de
escrever.
Independente da Interface do Usuário (UI) - É fácil
trocar a IU da Web por uma IU de Console ou Angular para Vue. A lógica está
contida no Core, portanto, alterar a IU não afetará a lógica.
Independente de banco de dados - inicialmente você
pode escolher SQL Server ou Oracle ou MySql, mas pode mudar para Mongo DB ou
Cosmos DB.
Independente de qualquer fator externo - O
Core da sua aplicação simplesmente não sabe nada sobre o mundo exterior;
E estamos
conversados...
"Que diremos, pois, a
estas coisas? Se Deus é por nós, quem será contra nós?"
Romanos 8:31
Referências: