CLEAN ARCHITECTURE

Descubra o que é Clean Architecture e quando vale apena usar.

blog-image

CLEAN ARCHITECTURE

O que é Clean Architecture?

A Clean Architecture foi criada por Robert C. Martin e promovida em seu livro Clean Architecture: A Craftsman’s Guide to Software Structure. Assim como outras filosofias de design de software, a Clean Architecture tenta fornecer uma metodologia a ser usada na codificação, a fim de facilitar o desenvolvimento códigos, permitir uma melhor manutenção, atualização e menos dependências.

Um objetivo importante da Clean Architecture é fornecer aos desenvolvedores uma maneira de organizar o código de forma que encapsule a lógica de negócios, mas mantenha-o separado do mecanismo de entrega.

image

Este diagrama pode ser um pouco confuso no início, então vamos dividi-lo.

Entidades: Entidades são uma das duas camadas de domínio do círculo interno que representam a lógica de domínio e de negócios. Elas são regras de negócio abrangentes em toda a empresa, ou coisas que sempre serão verdadeiras ou estáticas para esta aplicação. As entidades podem ser um objeto com métodos ou apenas uma coleção de estruturas de dados e funções. Elas encapsulam o nível mais geral ou superior e, portanto, têm menos probabilidade de mudar devido a uma mudança em uma camada externa.

Por exemplo, as funcionalidades principais de um aplicativo não seriam alteradas ao trocar o framework front-end de React para Angular.

Casos de Uso: Casos de Uso são a segunda camada de domínio. Ela define regras de negócio específicas da aplicação. Os casos de uso encapsulam e implementam todos os casos de uso aprovados para a aplicação. Os casos de uso controlam o fluxo de e para as entidades e podem chamar as entidades para usar suas regras de escala empresarial para concluir determinadas tarefas do usuário.

Mudanças nesta camada não afetarão as entidades ou camadas mais externas. No entanto, esta camada terá que ser alterada se as camadas externas forem alteradas.

Adaptadores de Interface: Esta camada adapta a entrada em um formato mais utilizável pelas camadas de casos de uso e entidades. Também formata a saída das entidades ou casos de uso em um formato mais adequado para os canais voltados para o exterior. A camada de adaptadores é a fronteira efetiva entre as camadas internas e externas do círculo. Nenhum código dentro desta camada deve conhecer ou referenciar algo mais externo do que esta camada.

Você pode pensar nos adaptadores de interface como um tradutor que converte e transmite informações de maneira mais utilizável pelas camadas internas e externas, respectivamente.

Framework e Drivers: Framework e Drivers é a camada de apresentação que geralmente é composta por frameworks e ferramentas como bancos de dados, frameworks web, e assim por diante. Esta camada não apresenta muito código, mas contém todas as referências concretas necessárias a detalhes específicos, como operações específicas do banco de dados ou comandos específicos do framework atual.

Benefícios da Arquitetura Limpa

Altamente Testável: A arquitetura limpa é construída desde o início com foco em testes. Você pode criar casos de teste para cada camada para determinar onde ocorrem erros dentro do círculo.

Como cada camada possui um papel definido, muitas vezes é óbvio onde ocorreu um erro. Isso também permite que você pule certos casos de teste, dependendo do que você atualizou, porque as camadas internas não devem ser afetadas por mudanças nas camadas internas.

Independente de Framework: A arquitetura limpa não depende de ferramentas de nenhum framework específico e não utiliza o framework como uma dependência em nenhum lugar do código.

Como resultado, você pode atualizar ou alterar o framework a qualquer momento com um trabalho mínimo necessário para a transição. Todas as camadas internas ainda devem funcionar mesmo se você adotar um framework diferente.

Independente de Banco de Dados: A maioria do seu aplicativo não precisa saber de qual banco de dados está obtendo dados. Isso significa que você pode adotar um novo banco de dados sem fazer alterações na maior parte do código-fonte.

Isso significa que você pode migrar instantaneamente de um banco de dados SQL para um banco de dados NoSQL, sem alterar nenhum código.

Independente de Interface do Usuário (UI): Os frameworks de interface do usuário existem na camada mais externa e, portanto, são apenas um apresentador para os dados passados pelas camadas internas.

Nada depende do apresentador, portanto você pode alterar o framework de UI a qualquer momento.

Desvantagens da Arquitetura Limpa

Diferentes problemas têm diferentes requisitos. A Clean Architecture e abordagens relacionadas enfatizam o desacoplamento, flexibilidade e inversão de dependência ao máximo, mas sacrificam a simplicidade. Isso nem sempre é vantajoso.

O precursor dessas arquiteturas é o padrão clássico MVC do Smalltalk. Isso separa o modelo da interface do usuário (controlador e visualização), para que o modelo não dependa da UI. Existem muitas variações de MVC, como MVP, MVVM, ...

Sistemas mais complexos não possuem apenas uma interface do usuário, mas possivelmente várias interfaces do usuário. Muitos aplicativos optam por oferecer uma API REST que pode ser consumida por qualquer UI, como um aplicativo da web ou um aplicativo móvel. Isso isola a lógica de negócios no servidor dessas UIs, para que o servidor não se importe com o tipo de aplicativo que o acessa.

Normalmente, o servidor ainda depende de serviços backend, como bancos de dados ou provedores de terceiros. Isso é perfeitamente aceitável e leva a uma arquitetura em camadas simples.

A Hexagonal Architecture vai além e para de fazer distinção entre frontend e backend. Qualquer sistema externo pode ser uma entrada (fonte de dados) ou uma saída. Nosso sistema principal define as interfaces necessárias (portas), e criamos adaptadores para quaisquer sistemas externos.

Uma abordagem clássica para desacoplamento forte é uma arquitetura orientada a serviços (SOA), onde todos os serviços publicam eventos em um barramento de mensagens compartilhado e consomem eventos dele. Uma abordagem semelhante foi posteriormente popularizada pelos microsserviços.

Todas essas abordagens têm vantagens, como facilitar o teste do sistema de forma isolada (substituindo todos os sistemas externos pelos quais ele se integra por implementações simuladas). Elas também facilitam a disponibilização de várias implementações para um tipo de serviço (por exemplo, adicionar um segundo processador de pagamento) ou a substituição da implementação de um serviço (por exemplo, migrar de um banco de dados Oracle para o PostgreSQL ou reescrever um serviço em Python para Go).

Mas essas arquiteturas são como Ferraris: caras e a maioria das pessoas não precisa delas. A flexibilidade adicional da Clean Architecture, etc., vem com o custo de maior complexidade. Muitos aplicativos, especialmente aplicativos da web CRUD, não se beneficiam disso. Faz sentido isolar coisas que podem mudar, por exemplo, usando modelos para gerar HTML. Faz menos sentido isolar coisas que provavelmente não mudarão, como o banco de dados subjacente. O que é provável de mudar depende do contexto e das necessidades do negócio.

Os frameworks fazem suposições sobre o que vai mudar. Por exemplo, o React tende a assumir que o design e o comportamento de um componente mudam juntos, então não faz sentido separá-los. Poucos frameworks assumem que você pode querer mudar o próprio framework. Portanto, os frameworks apresentam um certo grau de dependência. Por exemplo, a dependência do Rails no (muito opinativo!) padrão Active Record torna difícil ou até impossível alterar sua estratégia de acesso a dados para o (geralmente superior) padrão Repository. Se suas expectativas de mudança não coincidem com o framework, pode ser melhor usar um framework diferente. Muitos outros frameworks da web não fazem suposições sobre acesso a dados.

Outro ponto muito critíco ao utilizar o clean arch, é a performance criar abstrações em cima de abstrações para fazer uma simples consulta no banco de dados, pode ser um problema, pois a cada camada que você adiciona, você adiciona um overhead, e isso pode ser um problema em sistemas que precisam de uma performance alta.

Uma outra desvantagem que eu vejo é que um dos princípios da clean arch é que você pode sempre trocar a sua camada exterior os seus serviços e apis e simplesmente vai continuar funcionando toda a lógica contruida anteriormente no seu UseCase, mas na prática não funciona assim você sempre vai ter que fazer alguma alteração no seu UseCase para que ele se adapte a nova camada exterior, por exemplo uma api de pagamento quando trocada vai obviamente mudar muita coisa, ou então um banco de dados ou ORM quando trocado também vai mudar muita coisa, então não é tão simples assim trocar a camada exterior e continuar funcionando. Isso soa muito como otimização prematura e uma frase bem famosa fala que "A otimização prematura é a raiz de todo o mal".

Conclusão

Mostrei um pouco dos benefícios e desvantagens da arquitetura limpa, mas acredito que a maior vantagem é a organização do código, pois com a arquitetura limpa você consegue separar bem as responsabilidades de cada camada, e isso facilita muito a manutenção do código, pois você sabe exatamente onde está cada responsabilidade, e isso facilita muito a vida de quem está entrando no projeto, pois ele consegue entender bem o que está acontecendo, e isso é muito importante para o sucesso de um projeto.

Porém me preocupa o seguinte nem sempre temos a necessidade de utilizar esse tipo de arquitetura para muitos casos ela é um overkill, e pode trazer mais problemas do que soluções, então é importante sempre analisar o contexto do projeto e ver se realmente vale a pena utilizar esse tipo de arquitetura.

Newsletter

Receba mensalmente uma curadoria de conteúdo com novidades sobre tecnologia, lançamento de produtos, tutoriais, artigos e design.


©2023   Roger Rocha