A Ilusão do Código Limpo: Quando a Abstração Custa Mais Cara que a Duplicação
Um mergulho nos custos ocultos do princípio DRY e por que a duplicação de código muitas vezes é mais barata que a abstração prematura.
Resumo executivo
Um mergulho nos custos ocultos do princípio DRY e por que a duplicação de código muitas vezes é mais barata que a abstração prematura.
Ultima atualizacao: 22/02/2026
Resumo executivo
Desde os primeiros dias de formação, todo engenheiro de software é doutrinado em um conjunto de princípios sagrados. Entre eles, o DRY (_Don't Repeat Yourself_) reina absoluto. A ideia é sedutora: se você escrever o mesmo código duas vezes, extraia-o para uma função, classe ou módulo compartilhado. Mas o que acontece quando esse mantra é levado ao extremo em sistemas corporativos complexos?
O resultado frequentemente não é um código "limpo", mas sim uma teia invisível de acoplamento. A busca incessante por remover a duplicação cria estruturas rígidas que resistem a mudanças. Em níveis seniores de arquitetura de software, a conversa muda: começa-se a questionar não se o código está duplicado, mas qual é o custo cognitivo e estrutural da abstração que foi criada para evitar essa duplicação?
Para Diretores de Engenharia e Arquitetos de Sistemas, entender o ponto de inflexão onde uma abstração passa de um facilitador para um gargalo de manutenção é crucial. Trata-se de uma decisão de negócio travestida de decisão técnica.
A ferramenta só gera ganho sustentado quando entra no fluxo padrão de engenharia com critérios claros de compatibilidade, rollout e rollback.
O que mudou e por que importa
Imagine o cenário clássico de desenvolvimento: a Equipe A escreve uma lógica de validação de usuários para o sistema de faturamento. A Equipe B precisa de uma validação similar para o sistema de relatórios. Um engenheiro bem-intencionado, seguindo o princípio DRY rigorosamente, extrai essa lógica para um pacote UserValidator compartilhado.
Nos primeiros meses, tudo funciona perfeitamente. Contudo, as regras de negócio começam a divergir. O faturamento requer validações fiscais assíncronas, enquanto os relatórios precisam de uma verificação rápida em cache para otimizar a velocidade de renderização.
Para acomodar ambos no mesmo pacote genérico, o UserValidator começa a receber flags booleanas (isAsync, bypassCache, strictMode). O que era um utilitário simples transforma-se em uma monstruosidade condicional. Isso é o que Sandi Metz genialmente categorizou:
"A duplicação é muito mais barata que a abstração errada."
O custo da abstração prematura manifesta-se de várias formas que drenam a velocidade de um time:
- Carga Cognitiva: Novos desenvolvedores levam dias para entender o fluxo de execução, pulando de arquivo em arquivo para decifrar dependências indiretas.
- Acoplamento Indesejado: Uma mudança inofensiva para a Equipe A quebra em produção os relatórios da Equipe B, gerando um incidente grave.
- Rigidez: A equipe perde autonomia para inovar porque tem medo de tocar no código "compartilhado" por medo dos efeitos colaterais.
Perguntas de decisão para o time técnico:
- Quais projetos devem ser piloto e quais precisam de estabilidade máxima?
- Como a mudança entra no CI/CD sem aumentar taxa de falha em produção?
- Qual plano de reversão garante recuperação rápida de incidentes?
Implicações de arquitetura e plataforma
À medida que a engenharia de software amadureceu, especialmente com a adoção de microsserviços e _domain-driven design_ (DDD), surgiu a percepção de que contextos diferentes frequentemente exigem modelos de dados independentes, mesmo que superficialmente pareçam idênticos.
WET (Write Everything Twice)
O princípio WET propõe que você só deve abstrair quando o mesmo padrão for escrito pela terceira vez. Escrevê-lo duas vezes (Write Everything Twice) permite observar com calma. Só quando o terceiro caso de uso genuíno aparece, você possui amostragem suficiente das regras de negócio para desenhar a abstração correta.
AHA (Avoid Hasty Abstractions)
Evitar Abstrações Precipitadas prega focar em otimizar para mudança, não apenas para reutilização. Um código levemente duplicado mas altamente legível e isolado é muito mais fácil de "desmontar" e refatorar no futuro do que uma abstração fortemente acoplada.
Aprofundamento técnico recomendado:
- Crie matriz de compatibilidade por runtime, dependência e infraestrutura.
- Separe rollout técnico de rollout funcional para isolar causa de regressão.
- Automatize checks de qualidade e segurança antes de ampliar adoção.
Riscos de implementação que costumam ser ignorados
Equipes de alta performance não evitam a abstração; elas a aplicam com parcimônia e contexto. Como líder técnico, é imperativo estabelecer "guardrails" culturais:
- Aceite as bordas do sistema: É aceitável (e muitas vezes desejável) duplicar modelos de domínio na camada de integração entre microsserviços distintos. Compartilhar a mesma DLL ou pacote NPM central de "Core Models" entre 30 microsserviços é a receita para criar um monólito distribuído fatal.
- Avalie o Eixo de Mudança: A duplicação é prejudicial se, e somente se, o conhecimento de domínio for o mesmo. Se dois blocos de código parecem iguais, mas mudam por razões governadas por atores diferentes na organização, eles não estão duplicados. É apenas uma coincidência temporal.
- Privilegie Composibilidade sobre Herança: Quando abstrair for inevitável, prefira funções pequenas, puras e desacopladas que possam ser compostas dinamicamente, evitando profundas árvores de herança que amarram o comportamento.
Riscos e anti-padrões recorrentes:
- Upgrade amplo sem canário e sem telemetria por serviço.
- Misturar mudança de ferramenta com refatoração de negócio na mesma entrega.
- Aceitar defaults sem avaliar impacto em custo, latência e ergonomia de time.
Plano técnico de otimização (30 dias)
Lista de tarefas de otimização:
- Definir baseline de compatibilidade por aplicação.
- Executar canário com métricas de erro e performance.
- Formalizar critérios de rollout progressivo.
- Documentar runbooks de rollback por cenário.
- Consolidar aprendizado no playbook da plataforma.
Checklist de validação em produção
Indicadores para acompanhar evolução:
- Taxa de falha de deploy após mudança de ferramenta.
- Tempo médio de rollback em incidentes de regressão.
- Produtividade do time após estabilização do novo fluxo.
Precisa aplicar esse plano sem travar o roadmap e com governança técnica real? Falar com especialista em arquitetura com a Imperialis para desenhar e implantar essa evolução com segurança.