Além dos Templates: Uma Crítica Construtiva à Arquitetura Limpa e a Adaptação Pragmática no Design de Software
Tags: softwareengineering, architecture, cleanarchitecture
Published: 2024-02-18 22:14:18

**YAN JUSTINO**
[MSc. Software Engineering](https://repositorio.ufrn.br/handle/123456789/26370) · [PhD. Student](https://www.cesar.school/doutorado-profissional-em-engenharia-de-software/)
[AWS](https://www.youracclaim.com/users/yan-justino/badges) · [MCSD](https://www.youracclaim.com/users/yan-justino/badges) · [OCA](https://www.youracclaim.com/users/yan-justino/badges) · [ORCID](https://orcid.org/0000-0001-7248-716X)  · [Tech Lead at ITAÚ Unibanco]()

![Static Badge](https://img.shields.io/badge/post-design-50A6C5?style=for-the-badge) 

----

> Mas não se preocupe, meu amigo
Com os horrores que eu lhe digo
Isto é somente uma canção
A vida realmente é diferente
Quer dizer, ao vivo é muito pior - **Belchior**

----

## 1. CONTEXTUALIZAÇÃO
 
As últimas duas décadas foram marcadas por mudanças significativas na forma em que modelamos, construímos, implantamos e mantemos softwares. Testemunhamos na indústria a consolidação do _Domain-Driven Design (DDD)_, a ascensão da _Cloud Computing_ e da _Service-Orientation_. 

Também presenciamos o surgimento de conceitos como _Data Lake_ e _Data Mesh_, que vieram ampliar os recursos e aspectos voltados à análise e tomada de decisão.Todos esses movimentos da engenharia de software possuem uma forte influência de design centrada nos aspectos de domínio de negócio. 

Imerso no contexto dessas transformações, lembro-me de discussões acaloradas nos fóruns de tecnologia sobre quão pobre eram as minhas aplicações modeladas usando conceitos como [MVC, Poco, Presentation, BLL e DAL etc](https://learn.microsoft.com/en-us/aspnet/web-forms/overview/data-access/introduction/creating-a-business-logic-layer-cs), em detrimento a poderosa e rica organização que oferecia o DDD. 

Lembro do entusiasmo e da forte influência dos meus gurus e de como em pouco tempo eu também me tornara um (chato) evangelista do Eric Evans, Vaughn Vernon e Scott Millet... 

> Amadurecer nos traz o benefício e a oportunidade de rir de nós mesmos.

Nas contas do tempo, me recordo de alguns pecados contra o DDD que nós, vigilantes e ávidos acólitos, estávamos prontos pra denunciar. Um deles é proibido de ser pronunciado até hoje: "DDD é um padrão arquitetural". Essa é uma lacuna conceitual que ainda persiste: há uma certa predileção por parte dos desenvolvedores aos [padrões táticos](https://learn.microsoft.com/pt-br/azure/architecture/microservices/model/tactical-ddd) do que os aspecto estratégicos do DDD. 

Nesse sentido, se criou um certo _imbróglio_. Desenvolvedores que passaram a adotar DDD tinham uma nítida impressão que estavam fazendo algo diferente: a organização de suas aplicações agora tinham uma estrutura mais semântica, mais expressiva e próxima a linguagem do negócio. No entanto, ter o benefício dessa organização não significava exatamente que a equipe de desenvolvimento tivesse aplicado as abordagens estratégicas do DDD. 

Nesse aspecto, dizer que sua aplicação usava um padrão arquitetural chamado DDD parecia, até certo ponto, incoerente. Esse tipo de confusão muitas vezes era respaldada por iniciativas como o [_DDD N-Layered .NET 4.0 Architecture Guide_](https://devblogs.microsoft.com/cesardelatorre/great-diagram-about-our-ddd-nlayered-net-4-0-architecture/), um guia que orientava como desenvolvedores poderiam organizar suas aplicações baseando-se em conceitos de DDD. Esse modelo foi amplamente disseminado e até hoje encontramos aplicações estruturadas seguindo essa proposta:

![DDD N-Layered Architecture](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/59id2runj5q4gsfuef45.png)
<p><small><b>Figura.</b> modelo em camadas aplicando DDD</small></p>

Posteriormente esse tipo de iniciativa também foi duramente criticada por "reduzir" os aspectos de domínio a uma mera organização de pastas que mais expressavam linguagem de software e não de negócio. 

> Nothing here talks about what the application does - **Uncle Bob.**

Nessa linha, o [Robert C. Martin (**Uncle Bob**)](https://blog.cleancoder.com) em uma emblemática talk na Ruby Midwest 2011, confrontou a comunidade de desenvolvedores Rails questionando-a o porquê de suas aplicações não expressar uma linguagem de negócio em seu _Top Level Architecture_. O vídeo dessa talk pode ser assistido no link a seguir:

{% embed https://youtu.be/WpkDN78P884?si=S8XT9DVLuvFZN-HS %}

Algo me leva a crer que o Uncle Bob, diante de toda sua experiência e percebendo os conflitos e lacunas conceituais de design da época, vislumbrou a oportunidade de pavimentar o caminho para mais uma de suas publicações, daquela que chamo de "cleanware" - livros com o título "X Limpo".

A [_Clean Architecture_](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html), é uma obra de 2017 que pertence ao conjunto de publicações que representa a visão idealizada de Robert C. Martin (**Uncle Bob**) sobre princípios e boas práticas no design de software. 

Segundo o autor, o objetivo da _Clean Architecture_ é o desenvolvimento de sistemas fáceis de manter, testar, e estender ao longo do tempo, além de promover a separação de responsabilidades em diferentes camadas.

Em pouco tempo a _Clean Architecture_ alcançou uma certa popularidade e influência sobre os projetos de software na industria. Ao meu ver, a fama do autor do "Código Limpo" somada as similaridades de design que os desenvolvedores já adotavam utilizando os padrões táticos de DDD, foram decisivos para o engajamento à _Clean Architecture_.

No entanto, analisando criticamente os projetos nos quais atuei e que fazem uso da _Clean Architecture_ como ferramenta para organização de software, me parece que há uma compreensão parcial sobre o uso do conceito aplicado as estruturas de aplicações. 

Muito embora a obra apresente algumas estratégias de organização de software e ser explicita que elas se aplicam a soluções monolíticas, é perceptível que há uma certa incoerência ao depararmos com várias aplicações adotando apenas uma das estratégias (a mais criticada pelo Uncle Bob, por sinal) e em todo tipo de projeto.  

O irônico é que no último capítulos do livro, "O capítulo perdido"(34), o Uncle Bob, fazendo uso de toda sua experiência, alerta:

>  Todas as orientações que você já leu até agora certamente o ajudarão a projetar softwares melhores [...] Mas acontece que o diabo está nos detalhes de implementação, e é realmente muito fácil cair no último obstáculo se você não pensar nisso um pouco também.

Como ocorre em outros temas na indústria de software, uma grande parcela dos profissionais não visitam as fontes originais de um determinado conhecimento e consomem indiretamente novos conceitos assumindo como verdade aquilo que alguns gurus lhes transmitiu.

Diante disso, esse artigo irá apresentar as estratégias de organização propostas no capítulo 34 do _Clean Architecture_, e em seguida fará uma breve avaliação sobre a visão apresentada pelo Uncle Bob.

## 2. DESIGN E ORGANIZAÇÃO DE CÓDIGO

O último capítulo, "O capítulo perdido" (34), da última parte (VI) do livro _Clean Architecture_ apresenta quatro abordagens dedicadas ao design e organização do código. As abordagens são: (a) Pacote por camada, (b) Pacote por recurso, (c) Portas e Adaptadores; e (d) Pacotes por componente. A seguir detalharemos cada uma dessas estratégias.

### Pacote por camada
Para Uncle Bob, a estratégia de pacotes por camada é uma das abordagens mais tradicionais. Nelas as camadas devem depender apenas da próxima camada adjacente mais baixa. 

Uma das vantagens em adota-la é a rapidez para fazer algo funcionar. Por outro lado, rapidamente as três camadas se mostram insuficientes para conter uma complexidade crescente. Além disso, a estrutura de camadas não expressa nada sobre o domínio de negócio. A figura a seguir ilustra esse modelo de organização.

![package by package](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aw8dsv31jooxnc1mh3sn.png)
<p><small><b>Figura.</b> representação da estratégia de pacotes por camada (própria)</small></p>


### Pacote por recurso
A estratégia de pacote por recurso é uma divisão vertical, com base em recursos relacionados a conceitos de domínio e Agregações (_Aggreate Roots_). Nesse modelo, todos os tipos são colocados em um único pacote. 

Essa abordagem pode ser conhecida também como _Vertial Slice Architecture_ e tem contornos bem particulares e interessantes na perspectiva de [Jimmy Bogard](https://www.jimmybogard.com/vertical-slice-architecture/)

Para Uncle Bob, a vantagem dessa estratégia é que ela "grita" algo sobre o domínio de negócio. Em contrapartida, ele é muito vago sobre as desvantagens, se limitando a dizer: 

> Se você leu este livro até aqui, deve estar pensando que podemos fazer muito melhor - e está certo!

A figura a seguir ilustra o modelo de organização de pacote por recurso.

![package by resource](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4w2r2vbgv8hhubmvlldu.png)
<p><small><b>Figura.</b> representação da estratégia de pacotes por recurso (própria)</small></p>

### Portas e Adaptadores
A estratégia de portas e adaptadores é rapidamente apresentada por Uncle Bob, que afirma que o objetivo dessa abordagem é criar arquiteturas onde o código de domínio é independente e separado de detalhes de implementação, como acessos a banco de dados. 

Também é conhecida como [Arquitetura Hexagonal](https://alistair.cockburn.us/hexagonal-architecture/). A figura a seguir ilustra o modelo de organização de portas e adaptadores.

![ports and adapters](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0wpbbx0wehgggo8nljiy.png)
<p><small><b>Figura.</b> representação da estratégia de portas e adaptadores (própria)</small></p>

Nos últimos anos, esse é o tipo de estrutura mais recorrente que identifico nos projetos. O mais estranho é que mesmo em aplicações que possuam apenas um escopo - e nem precisa ser de negócio, essa estrutura pôde ser identificada. 

Na maioria dos casos, esse tipo de implementação em soluções dotnet apresenta um certo relaxamento na relação entre as camadas de apresentação e infraestrutura, ao permitir que detalhes de implementação de infra vazem durante a injeção de dependências, quando orquestrada pela camada web. 

### Pacote por componente
A estratégia de pacote por componente é nitidamente a abordagem que parece ter a maior empatia de Uncle Bob, uma vez que ela é uma abordagem híbrida que contempla as demais estratégias. 

Essa abordagem agrupa todas as responsabilidades relacionadas a um único componente de alta granularidade, mantendo as interfaces de usuários separadas desse único pacote.

Na concepção do autor, podemos "pensar nos componentes bem definidos de uma aplicação monolítica como um degrau rumo a uma arquitetura de microsserviços". 

Esse pensamento me remete a uma prática emergente denominada como [Modular Monolith](https://awesome-architecture.com/modular-monolith/). A figura a seguir ilustra o modelo de organização de pacote por componente.

![package by components](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rzj969qz5m1c7g5f7xwx.png)
<p><small><b>Figura.</b> representação da estratégia de pacotes por componente (própria)</small></p>

Colocando em perspectiva todas as estratégias de organização propostas pela _Clean Architecture_ podemos ter a seguinte visão comparativa ilustrada na figura a seguir.

![all strategies](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9e14l03qcfje4zeqe9u9.png)
<p><small><b>Figura.</b> visão comparativa das estratégias (própria)</small></p>

Diante das abordagens apresentadas, é preciso questionar o quanto as equipes ponderam e racionalizam sobre as decisões de design na hora de construir aplicações? Será que as equipes tem adotado a _Clean Architecture_ apenas como um template de código na busca de organização?

É preciso reforçar que a _Clean Architecture_ não contempla a arquitetura de software como um todo. Na verdade ela representa apenas uma das atividades dentro da etapa de _Architectural Design_ no ciclo de vida da Arquitetura de Software. Para entender mais sobre esse ciclo, recomendo a leitura do livro [Designing Software Architectures: A Practical Approach](https://www.oreilly.com/library/view/designing-software-architectures/9780134390857/).

## 3. PONDERAÇÕES SOBRE A CLEAN ARCHITECTURE E SEU AUTOR

Embora a intenção seja promover a flexibilidade, a estrutura proposta pela _Clean Architecture_ pode, paradoxalmente, resultar em rigidez. Alguns críticos argumentam que aderir estritamente a essas regras pode dificultar a adaptação a requisitos de projetos específicos, novas tecnologias ou métodos de desenvolvimento emergentes. O próprio Uncle Bob alerta: 

> Leave options open where applicable, but be pragmatic, and take into consideration the size of your team, their skill level, and the complexity of the solution in conjunction with your time and budgetary constraints.

Outra crítica comum é que a _Clean Architecture_ pode levar ao overengineering, onde o esforço para manter o software "limpo" supera os benefícios práticos. Isso pode desviar o foco de entregar funcionalidades valiosas para o usuário final para se concentrar excessivamente na estrutura interna do código.

É importante ter em mente que o Uncle Bob é uma figura controversa. Suas obras são cheias de afirmações fortes e que precisam ser ponderadas ao lê-las. Existem capítulos inteiros no _Clean Architecture_ que podem ser contestados à luz da ciência e de pesquisas já validadas antes mesmo da obra ser lançada.

No entanto, é inegavel sua contribuição à indústria e seu poder de engajamento na comunidade de desenvolvedores. Sua larga experiência e senso pragmático aguçado criaram conceitos cujos benefícios já foram igualmente atestados [[1]](https://sol.sbc.org.br/index.php/cbsoft_estendido/article/view/14620/14465)[[2]](https://link.springer.com/chapter/10.1007/978-3-031-47372-2_8).

Como em qualquer metodologia ou padrão de design, é importante avaliar as necessidades específicas do projeto e o contexto para determinar a abordagem mais apropriada.

## 4. CONCLUSÃO

O artigo aborda a evolução das práticas de engenharia de software, com foco na _Clean Architecture_ de Robert C. Martin (Uncle Bob), ressaltando a importância de adaptar os princípios de design ao contexto específico de cada projeto. Ele critica a adoção superficial da _Clean Architecture_, que muitas vezes resulta em complexidade desnecessária ou overengineering, e destaca a necessidade de uma reflexão crítica sobre as decisões de design.

Além disso, aponta para a relevância de considerar as características únicas de cada equipe e projeto ao aplicar conceitos como Pacote por Camada, Pacote por Recurso, Portas e Adaptadores, e Pacote por Componente. Também enfatiza a figura controversa de Uncle Bob, reconhecendo suas contribuições, mas também alertando para a necessidade de questionar e ponderar suas afirmações.

Em resumo, defende uma abordagem pragmática e adaptável ao design de software, priorizando soluções que atendam às necessidades reais dos projetos e promovam uma linguagem de negócio clara e uma arquitetura sustentável, além de enfatizar a importância de ir além dos templates e regras predefinidas para alcançar uma verdadeira valorização do software para os usuários finais.

---

Caros leitores,

Espero que tenham encontrado insights valiosos na discussão sobre o design e organização de código.

Se você já experimentou essas estratégias em seus projetos, como foi? Quais vantagens e obstáculos você encontrou? Se ainda não tentou, consideraria implementá-la após essa leitura?

Seu feedback é crucial para enriquecer essa discussão.