Como eu acho que deveríamos enxergar software agora

Como eu acho que deveríamos enxergar software agora

Introdução

Eu sou um daqueles desenvolvedores que está odiando o hype - ou como quiser chamar - da inteligência artificial, não gosto da velocidade que ela está nos obrigando a seguir no dia a dia e também não gosto de não escrever código efetivamente, isso era uma das coisas que mais me gerava dopamina.

Portanto, a ideia de escrever sobre isso é para que eu consiga começar a enxergar coisas positivas ou estratégias de para onde eu posso ir. Desde que comecei a gostar de backend, mais ou menos 6 anos atrás, eu me interessei por arquitetura de software. Logo, quero discorrer aqui sobre esse tema nos tempos atuais.

Quero adicionar o que seria uma nota de rodapé: essa escrita não tem nenhum intuito de mudar sua opinião, quero apenas buscar entender qual a minha utilidade nesse período da tecnologia e como posso voltar a gostar de desenvolvimento de software. Tanto que não terá nenhum uso de IA nesse texto, nem para revisão, muito menos para escrita - apenas para gerar a imagem, já que não sou artista.

Clean Architecture, Hexagonal e outros padrões

Já começo falando que eu gosto desses padrões não tenho nada contra eles diretamente. Acho que o grande problema está nos desenvolvedores, de levarem sempre seu padrão como perfeito e naturalmente superior a qualquer coisa, não os veem como ferramenta, mas sim como uma forma sagrada de resolver todos os problemas - provavelmente eu mesmo faça isso com meu novo xodó de arquitetura de código, o Package by Feature, mas irei falar mais sobre isso posteriormente.

Eu entendo que são padrões que em algum momento resolveram uma dor latente da indústria e o quão importante foram para o surgimento de novas ideias. O Clean Architecture por exemplo, resolveu o desacoplamento, facilitou a escrita de testes e melhorou a coesão do código. Já o Hexagonal Architecture veio para, de forma simples, separar o domínio da infraestrutura e tem basicamente os mesmos ganhos que Clean Architecture. O SOLID se contradiz nas próprias letras, mas também trouxe benefícios.

Mas acho de suma importância os conceitos que podemos aprender com esses padrões e que devemos sim estudar cada um deles, por quê, de forma estratégica, são sem dúvidas essências para o nosso trabalho.

Entretanto, o quanto disso faz sentido de forma tática? Com o Clean Arch - sim, cansei de escrever o nome inteiro - para eu criar um simples CRUD eu vou ter que escrever de 10 ~ 15 arquivos de código, o hexagonal não vai muito longe disso. Seguinte o SOLID, eu deveria me importar com Dependency Inversion e criar uma abstração para que meu domínio e minha infraestrutura dependam dela e assim aumentar a carga cognitiva do meu código.

You Ain't Gonna Need It - YAGNI

Para quem não conhece esse mantra do ágil, ele basicamente diz que: você não deveria implementar funcionalidades, códigos ou melhorar perfomance até que realmente precise disso, assim não criaria complexidades para alterações futuras. Afinal de contas, o seu sistema com mil usuários precisa de uma arquitetura robusta e complexa? Vibe arquitetura evolutiva, mas isso é papo pra outra escrita.

Eu vou mudar meu banco de dados de Postgres para MySQL? Eu vou mudar minha ferramenta de Cache? Eu vou mudar meu provedor de pagamentos? Ok, aqui talvez mude, mesmo assim é difícil acontecer.

Eu acredito que existam empresas que mudem as ferramentas o tempo inteiro, mas se isso não é algo comum no seu negócio, não deveria escrever diversos arquivos de classes e interfaces pensando que "Ah! Em algum momento nós vamos mudar ferramenta X por Y, então devemos escrever assim", isso apenas vai aumentar a quantidade de arquivos no seu código e não terá ganho algum.

O meu novo xodó em arquitetura de código

Ao entrar no meu emprego atual, no ano passado, eu comecei a estudar mais sobre Golang, que é a linguagem que utilizamos aqui. Logo de cara já vi que é uma linguagem menos verbosa e mais simples. O primeiro projeto em que comecei a escrever em Go é um monolito que temos aqui e que é estruturado - ou tenta ser - em Clean Arch.

Assim que comecei a entender mais sobre a linguagem me pareceu estranho criar tantos arquivos em Go, parecia complexidade desnecessária, até pesquisar e entender que a linguagem encoraja criar pacotes coesos e alto contidos. Desse jeito acabei encontrando o Package by Feature.

Essa arquitetura de código milagrosa, que resolverá todos os seu problemas - ou não - é baseada em criar uma estrutura flat, onde cada funcionalidade no sistema é um pacote. Portanto, para eu criar um usuário eu teria um pacote CreateUser com seus devidos arquivos: controller; service; repository; de forma simples e direta.

Caso você queira entender mais sobre Package by Feature, nas referências vou deixar um artigo ótimo para isso.

Inteligência Artificial e o desenvolvimento de software

O mercado está pedindo velocidade, estamos sendo cobrados por isso, portanto aqui já podemos assumir que não estamos escrevendo código. Entendo que agora muitos estão com o papel de revisores do código escrito por IA, o que talvez não faça muito sentido.

Agora, por que eu escrevi tudo isso antes de chegar nesse tópico? Queria apenas lembrar deixa fresco na cabeça os conceitos e estruturas.

Portanto, pensando em utilizar IA para escrever código nós precisamos nos atentar a alguns pontos: perde memória entre sessões; limitação da janela de contexto; qualidade do prompt. Isso pensando apenas superficialmente, para começar.

Para cada sessão, seu agente vai precisar ler a base inteira de código para entender o código, ter contexto e conseguir implementar. Obviamente ele vai precisar ler todos os 32 arquivos que você precisou escrever para criar um usuário, baseado em seu Clean Architecture. Assim, ele vai gastando diversos tokens. Você não tem documentação das decisões, não tem linter que force uma estrutura de código. Após os tokens gastos a IA gera um excelente código quebrado ou que não cobre tudo que você precisa.

Isso assumindo que você tem apenas um monolito. Agora se assumirmos uma arquitetura baseada em microserviços, a coisa já fica bem mais complexa. Se uma feature depende de mais de um microserviço, fazer os códigos se conversarem quando são escritos por IA é custoso, em energia e dinheiro.

Monorepo, boas documentações e linters

Precisamos começar a olhar com bons olhos organizar nossos serviços, seja apenas API e Frontend ou microserviços, com monorepo. Por que através disso, podemos compartilhar as skills de agentes; documentações como: Architecture Decision Records, Product Requirement Documents e Request For Comments; linters e quaisquer outras padronizações. Em apenas um local, juntamente com o código de cada um dos nossos serviços.

Então também podemos criar linters que não permitam um serviço importar funcionalidades de outros, ou seja, ter os bounded contexts como manda o Domain-Driven Design. Criar bons testes - que realmente funcionam - para garantir que os agentes não quebraram nada.

Logo, se tivermos toda essa estrutura robusta e, para arquitetar nosso código, seguirmos um design mais flat, como Package by Feature, conseguiremos tirar maiores proveitos do uso de IA. Iremos economizar energia do agente para entender tudo e, assim, ele poderá focar em desenvolver. Então, você não vai precisar ficar revisando código - afinal, a IA escreve código melhor que você, o problema é a falta de ferramental que ela possui para entender.

Aqui quero citar o Fabio Akita, não gosto de grande parte das coisas que ele fala, mas recentemente no podcast do Flow ele disse "A IA reflete quem você é". Logo, se a IA está gerando código ruim, talvez o problema não seja ela. Porém, aqui eu também vejo que o problema pode não ser apenas nós, desenvolvedores, mas também são as empresas, que nos obrigam a ter muita celeridade no desenvolvimento, então parar para analisar e conseguir criar uma estrutura dessas fica difícil.

A minha conclusão

Precisamos parar de olhar para o código como se um humano estivesse lendo - claro, não vamos levar ao pé da letra isso, por que quando estoura bug em produção é nós que precisamos ler e resolver - e entender que a IA não se preocupa com grande parte das divisões que fazemos no código, isso pra ela é apenas desperdício de energia.

Portanto, para o desenvolvimento moderno, acredito que podemos estar mais focados em: observabilidade; cobertura de testes e de mutação; entendimento da arquitetura macro; separação de agregados; threat modeling; entre outros.

Deixo aqui a frase "A computer can never be held accountable, therefore a computer must never make a management decision" do Manual da IBM de 1979. Numa tradução direta, diz que um computador não poderá ser responsabilizado, logo ele nunca deve tomar decisões gerenciais.

Nós, desenvolvedores; engenheiros; analistas; arquitetos; temos que ter a responsabilidade das decisões que realmente importam, que vão fazer o negócio escalar. Agora, a nível de código deixa que a IA pensa.

Referências

Clean Coder Blog
Dependency inversion principle - Wikipedia
bliki: Yagni
Yagni (“You Aren’t Gonna Need It”) is the principle that we should not build presumptive features. It should not be used as a justification for neglecting internal quality.
Why You Don’t Need Clean Architecture for Every Go Service
A pragmatic look at when Clean Architecture helps — and when it quietly adds unnecessary complexity to Go codebases.
Standard Package Layout
Addressing one of the biggest technical problems in the Go community
Why Clean Architecture Struggles in Golang and What Works Better
Golang has carved out a solid reputation as a fast, efficient language that prioritizes simplicity,…
Package by Feature
Package by feature to create self-contained and independent packages that are easy to understand and less error-prone
The ‘Lost in the Middle’ Problem — Why LLMs Ignore the Middle of Your Context Window
You stuffed all the right documents into the prompt. The LLM still got the answer wrong. Turns out, language models have a blind spot — and it’s right in the middle. Here’s the research behind it and what you can do.
Monorepo Explained
Everything you need to know about monorepos, and the tools to build them.