Prefira duplicação em vez da abstração errada (2016)
“Prefira duplicação em vez da abstração errada” revisita a troca entre repetir código e criar abstrações compartilhadas, argumentando que abstrações prematuras ou mal ajustadas frequentemente introduzem mais complexidade e acoplamento do que removem. Os comentários exploram heurísticas como a “regra de três”, a importância de distinguir semelhança casual de comportamento realmente compartilhado e a dor de longo prazo tanto de frameworks superengenheirados quanto de uma vasta quantidade de copy-paste. Vários observam que ferramentas modernas e LLMs alteram o perfil de custo da duplicação e da refatoração, mas que o desafio central continua sendo uma arte: encontrar abstrações estáveis e apropriadas ao domínio sem forçá-las cedo demais.
Escopo do Debate: Duplicação vs. Abstração
- Muitos concordam com a ideia central: abstrações prematuras ou “erradas” podem ser mais prejudiciais do que uma pequena duplicação local.
- Outros contrapõem que a duplicação em grande escala pode se tornar catastrófica, especialmente em sistemas de longa duração, com vários clientes ou várias equipes.
- Vários argumentam que o slogan costuma ser lido de forma errada; ele diz respeito a evitar abstrações prematuras ou casuais, não a uma licença para copiar e colar para sempre.
Quando a Duplicação é Útil
- Implementações repetidas podem ser uma ferramenta para descobrir a abstração correta: “faça duas ou três vezes, depois refatore” (regra de três / WET).
- A duplicação é vista como mais barata e mais segura no início, especialmente quando os requisitos de negócio e as fronteiras do domínio ainda não estão claros.
- Alguns preferem fluxos isolados, um pouco duplicados, em vez de uma “abstração deus” frágil com muitas flags e condicionais.
Quando as Abstrações Dão Errado
- Exemplos: frameworks excessivamente genéricos, polimorfismo forçado, “monólitos distribuídos” em microservices, frontends pesados em Redux e DRY levado ao extremo.
- Abstrações erradas tendem a:
- Codificar semelhanças acidentais em vez de conceitos realmente compartilhados.
- Espalhar acoplamento oculto, tornando cada mudança arriscada e global.
- Acumular parâmetros booleanos/de configuração e cadeias de chamadas complexas.
- Alguns sustentam que qualquer abstração mantível é melhor do que duplicação generalizada além de uma escala “de minimis”; outros discordam fortemente.
Heurísticas e Regras Práticas
- Heurísticas comuns:
- Não abstraia após uma única ocorrência; considere após duas; aja após três, se elas realmente representarem o mesmo conceito e mudarem pelas mesmas razões.
- Prefira abstrações que sejam óbvias e se justifiquem por sua própria interface, não apenas pelo conhecimento dos chamadores.
- Favoreça acoplamento frouxo e bibliotecas de suporte simples em vez de frameworks profundos, centralizados e “espertos”.
- Abstraia para facilitar a substituição futura, não para reutilização especulativa.
LLMs e a Curva de Custo
- Alguns observam que LLMs tornam a duplicação mais barata de criar e refatorar, potencialmente deslocando a balança para código mais simples e mais duplicado.
- Outros relatam que LLMs introduzem mais duplicação e podem deixar passar todas as ocorrências ao refatorar, então as abstrações ainda importam.
- A visão geral: a IA muda a economia, mas não elimina a necessidade de raciocinar sobre abstração vs. duplicação.