Às vezes, a maior barreira para começar um projeto não é a complexidade do problema, mas a busca por uma solução perfeita antes mesmo da primeira linha de código.
Na semana passada decidi criar um pacote Laravel para integrar a API do Asaas.
A ideia parecia simples: construir algo reutilizável para projetos futuros e, de quebra, aprender mais sobre desenvolvimento de pacotes.
Foi então que eu:
- Abri a IDE e comecei a criar um cliente HTTP simples para a API da Asaas.
- 15 minutos depois, eu já estava pesquisando sobre arquitetura de pacotes open source.
- Pensei em DTOs.
- Pensei em interfaces.
- Pensei em Services
O que eu entendia por "perfeito"?
Na minha cabeça, um projeto bem feito precisava nascer parecido com os grandes projetos open source que eu admirava.
Antes mesmo de validar a ideia, eu já pensava na arquitetura, na escalabilidade e em como aquele pacote pareceria para quem abrisse o repositório. E em outros cenários como:
- pensar na mesma arquitetura que grandes projetos usam antes de ter o primeiro caso de uso funcionando;
- tentar abordar todos os pontos da API da Asaas logo no começo, mesmo sem saber quais eu realmente ia usar;
- imaginar os atrativos que meu pacote teria para outros quererem usá-lo, antes de ele fazer qualquer coisa útil.
No papel, parecia que eu estava pensando como alguém mais experiente, mas na prática, eu estava:
apenas adiando a parte mais importante que era escrever código que resolvesse um problema real.
O custo disso na prática
O curioso é que eu terminava o dia com a sensação de que tinha trabalhado bastante. Tinha lido sobre arquitetura, desenhado camadas, esboçado interfaces.
Só que, olhando para o projeto, praticamente nada tinha sido construído: nenhuma requisição enviada, nenhum teste rodando, nenhuma prova de que qualquer uma daquelas decisões fazia sentido.
Com o tempo, isso começou a gerar um padrão:
- Mais tempo buscando a estrutura "perfeita" do que resolvendo o problema real;
- Código difícil de entender por estar "bem arquitetado" demais, cedo demais;
- Medo de refatorar algo que ainda nem tinha provado valor;
- Uma frustração crescente por sentir que eu não estava evoluindo, só girando em torno da mesma decisão de design.
Não era falta de qualidade. Era complexidade antecipada.
O que eu estava realmente evitando?
Foi só depois que comecei a me perguntar outra coisa: por que eu estava tão preso nisso?
Algumas hipóteses:
- Eu estava evitando escrever código que eu soubesse, de antemão, que ia precisar refatorar depois?
- Eu tinha medo de escrever algo "ruim" e isso aparecer publicamente num repositório open source?
- Eu queria provar, pra mim mesmo, que conseguia arquitetar "como um sênior" antes mesmo de ter o problema resolvido?
A resposta provavelmente era um pouco de cada uma. E nenhuma delas tinha relação com o problema que o pacote deveria resolver.
Só bem depois entendi que, no fundo, eu confundia complexidade com maturidade técnica.
O aprendizado que começou a aparecer
Enquanto refletia sobre isso, lembrei de uma frase que minha mãe repetia desde que eu era pequeno:
"Antes feito do que perfeito."
Sempre achei que essa frase servia para tarefas do dia a dia, como arrumar o quarto, terminar um trabalho da escola. Nunca imaginei que ela fizesse tanto sentido ao escrever software.
Junto com ela, veio outra ideia:
Bons sistemas não nascem perfeitos. Eles evoluem.
Nenhum dos projetos open source que eu admirava nasceu com a arquitetura que tem hoje; todos passaram por versões mais simples, mais cruas, que foram se modificando à medida que o uso real foi aparecendo.
Qualidade não está em prever todos os cenários.
Qualidade está em escrever código que consiga mudar quando esses cenários realmente aparecerem.
Foi só quando parei de procurar a arquitetura perfeita que finalmente escrevi minha primeira requisição de verdade para a API.
Antes mesmo de escrever a primeira integração, era assim que eu imaginava o pacote:
CustomerService
↓
AsaasClient
↓
CreateCustomerDTO
↓
Response
Mas não comecei com uma arquitetura cheia de camadas. Comecei com algo assim:
$asaas->customers()->create([
'name' => 'Yuri Souza',
'cpfCnpj' => '12345678909',
]);
Desde então, passei a repensar algumas atitudes:
- resolver o problema atual com clareza antes de pensar no próximo;
- manter o código simples, legível e testável;
- criar abstrações apenas quando um padrão se repete de fato, não quando eu imagino que ele vai se repetir;
- aceitar que refatorar faz parte do processo, não uma falha dele.
Não se trata de abandonar boas práticas, mas de aplicá-las no momento certo.
O equilíbrio que estou buscando hoje
Hoje tento encontrar um equilíbrio entre dois extremos: nem escrever código sem critério, nem criar uma arquitetura complexa antes que ela seja necessária.
No próprio pacote do Asaas isso já mudou a forma como estou trabalhando.
Hoje, a decisão que tomei foi outra: começar pelo caminho mais curto possível.
Primeiro quero que o pacote consiga conversar com a API e validar os casos de uso mais importantes. Só então vou descobrir quais abstrações realmente fazem sentido.
Em vez de tentar prever a arquitetura que o projeto terá daqui a um ano, prefiro deixar que ela se desenvolva à medida que novos problemas surgirem.
Foi aí que entendi uma coisa importante:
Arquitetura não é algo que eu preciso descobrir antes de começar. É algo que o próprio projeto vai mostrando à medida que cresce.
Conclusão
Ainda estou no começo desse pacote, e ainda estou aprendendo isso na prática, errando e ajustando no caminho.
Mas entender que "perfeição antecipada" pode virar um problema já foi um passo importante na minha evolução como desenvolvedor. O projeto do pacote Asaas não precisa da arquitetura perfeita logo de início; precisa apenas da primeira implementação. O resto vai aparecer conforme o uso real for mostrando o caminho.
Hoje prefiro um código simples que aceite mudanças a uma arquitetura impecável que resista a qualquer alteração.
Se você também já caiu nessa armadilha da arquitetura perfeita antes da hora, quero saber: como você percebeu e o que fez para sair dela?
A discussão continua nos comentários. Quero muito conhecer outras experiências e perspectivas sobre esse tema.
Agradecimentos: obrigado a @vitoriazzp pelo feedback sincero e pelas sugestões que ajudaram a tornar este artigo mais claro e útil.

Top comments (6)
Feliz na que ce finalmente publicou!
Tenho certeza de que a tua descoberta vai ajudar um monte de gente, afinal a gente sempre bate a perna em querer tudo redondinho pelo menos uma vez nessa área kkkk
Sim, o segundo de muitos. Quem sabe não vem mais outro por ai, e mais uma vez obrigado pelos os feedbacks
Eu estava refletindo sobre algo parecido uns dias atrás. Às vezes ficamos tão travados querendo aperfeiçoar algo que nem existe ainda, sendo que para o projeto ficar perfeito ele precisa começar. É a clássica procrastinação disfarçada de produtividade. Gostei da ideia de começar pelo caminho mais curto, resolver o caso de uso mais simples primeiro em vez de tentar prever toda a arquitetura antes de escrever a primeira linha.
Parabéns pelo artigo!
Isso que me pega em todo projeto pessoal que eu idealizo, por onde começar de maneira "certa". Mas escrevendo isso me fez refletir e consegui resolver mesmo que por um momento esse problema.
Obrigado, primo
Muito bom o artigo, primo!
Obrigado, prima!