Code Duplication: você corrige o bug. Em produção, ele continua aparecendo. Sabe por quê?

    Você corrigiu uma cópia da lógica. Existem outras duas que você não sabia que existiam. Os testes da função "oficial" passam. O caminho que o usuário X executou foi corrigido. O caminho de Y e Z, não. Bem-vindo ao perigo silencioso da duplicação.

    Você corrige o bug. Em produção, ele continua aparecendo. Os logs mostram que a correção subiu. Os testes passam. Mas o cliente relata o mesmo problema na semana seguinte. Code Duplication é a métrica que explica por quê.

    TL;DR

    Code Duplication é a replicação do mesmo comportamento em múltiplos pontos do sistema. Diferentemente das outras métricas, o problema é espalhado — não fica concentrado em um único arquivo. O perigo maior é a falsa sensação de segurança: você corrige uma cópia, e o bug continua nas outras. Com IA generativa, o problema acelerou.

    Para quem  Quem já viveu "achei que tinha corrigido" Leitura  ~6 min Funil  Awareness → Consideration

    What this article explores:

    • O cenário típico: bug que volta após "correção" — uma cópia corrigida, duas outras esquecidas
    • O que conta como duplicação — quatro tipos de clones detectados por análise estática
    • Por que duplicação é diferente das outras métricas (problema espalhado, sem epicentro)
    • A falha oculta — o risco real da falsa sensação de segurança
    • Os três custos sistêmicos: persistência de bugs, desperdício cognitivo, inconsistência
    • Por que IA generativa piorou o problema — duplicação silenciosa via prompts
    • DRY vs WET — o princípio operacional, sem fanatismo
    • Plano operacional em 5 passos para começar hoje
    • Cinco pontos-chave para levar embora
    § 1 Cena

    Você recebe o ticket de produção: o cliente está vendo o desconto errado. Investiga. Encontra a função calculateDiscount. Identifica o bug — uma comparação trocada. Corrige. Escreve o teste. Sobe pra staging, valida. Sobe pra produção.

    Uma semana depois, o ticket volta. Mesmo cliente. Mesmo sintoma.

    Você reabre. Vai no log. O método calculateDiscount que você corrigiu está sendo chamado, sim — mas existe outro lugar no sistema que não chama essa função. Em vez disso, tem uma cópia da lógica embutida diretamente no controller. Outro autor, três anos atrás, copiou e colou. Esse caminho do código nunca foi corrigido.

    Esse é o cenário típico de Code Duplication. E o detalhe perverso: você não tem como saber, na hora da correção, que existem outras cópias. Os testes da função que você corrigiu passaram. O comportamento daquele caminho está correto. O problema é que outro caminho usa lógica paralela, independentemente de quantos testes você adicionar à função "oficial".

    O que conta como duplicação

    A definição operacional é direta: mesmo comportamento lógico em mais de um lugar, sem reuso. Não precisa ser cópia literal — análise estática moderna detecta:

    Tipo 01
    Cópia literal
    Trecho idêntico, character-by-character.
    Tipo 02
    Cópia com renomeação
    Mesma estrutura, variáveis renomeadas.
    Tipo 03
    Cópia com modificação local
    Mesma estrutura, com algumas linhas adicionadas/removidas.
    Tipo 04
    Cópia semântica
    Implementação diferente, comportamento equivalente. Mais difícil de detectar.
    § 2 Tipologia

    A análise via Clone Detection roda em milhões de linhas em segundos. Ferramentas referenciais: PMD/CPD (Copy-Paste Detector), jscpd (multi-linguagem), Simian (Java/C#/Python), e a categoria de Clone Detection em ferramentas modernas de análise estática — incluindo a plataforma SQA da Codurance, que integra Code Duplication com as outras quatro métricas da série em um diagnóstico unificado.

    Por que duplicação é diferente

    As métricas anteriores da série — Ciclomática, Cognitiva, Smells, Bugs — medem problemas agrupados. A complexidade fica em uma função densa; o smell fica em uma classe específica; o bug lógico fica em uma linha. Você consegue apontar o lugar.

    Duplicação é o oposto: o problema está espalhado. Não tem epicentro. A mesma lógica vive em N lugares, e cada um deles parece, isoladamente, normal. Você só vê o problema quando olha para o sistema como um todo.

    Isso muda completamente a estratégia de remediação. Quanto à complexidade, você refatora a função problemática. Para duplicação, você precisa identificar o conjunto, escolher a "cópia autoritativa" (ou criar uma nova função que substitua todas as existentes) e migrar cada uso. É refatoração coordenada.

    A falha oculta — o risco real

    A periculosidade da duplicação não está no espaço em disco que ela ocupa. Está na falsa sensação de segurança.

    Cenário concreto: três cópias da mesma lógica, em três lugares diferentes. Bug é descoberto na cópia A. O dev corrige a cópia A. Roda os testes que conhece. Tudo verde. Sobe pra produção.

    Fig. 1 — Correção parcial em código duplicado
    Cópia A
    controllers/orders.js
    ✓ CORRIGIDO
    Path do usuário X. Testes passam. Comportamento ok.
    Cópia B
    services/billing.js
    ✗ AINDA QUEBRADO
    Path do usuário Y. Bug persiste. Comportamento errado.
    Cópia C
    jobs/discount-batch.js
    ✗ AINDA QUEBRADO
    Path do usuário Z. Bug persiste. Job noturno errado.
    O ticket "fechado" no path A reabre na semana seguinte, vindo do path B. O dev olha o log e fica confuso — a correção foi aplicada e está em produção. Como o bug ainda existe?
    § 3 Custo

    Em produção, o caminho do usuário X passa por A. Comportamento corrigido — bug resolvido. Os caminhos dos usuários Y e Z passam por B e C. Comportamento ainda errado — bug continua, intermitente, "reaparecendo".

    O dev olha o log e fica confuso. A correção foi aplicada, validada e está em produção. Como o bug ainda existe? A resposta é que a correção foi parcial — e ele não tinha como saber. Os outros dois pontos de execução não estão mapeados em lugar algum.

    Esse cenário gera três custos

    1. Persistência de bugs pós-correção. Erro sobrevive em cópias ocultas. Retrabalho garantido.
    2. Desperdício cognitivo. Time gasta energia analisando variações da mesma lógica em locais diferentes.
    3. Inconsistência sistêmica. O software apresenta comportamentos distintos para a mesma regra, dependendo de qual "cópia" foi executada.

    O terceiro é o mais grave em sistemas com regras de negócio: a empresa promete uma coisa; o software entrega outra dependendo do caminho. Confiança quebrada.

    “

    Antes do Copilot, duplicação era escolha consciente. Com IA generativa, virou silenciosa — cada prompt potencialmente vira uma nova cópia.

    § 4 IA

    A IA piorou o problema

    Antes do Copilot/Cursor/Claude, a duplicação era feita por meio de copy-paste consciente. O dev sabia que estava replicando. Era uma escolha (geralmente ruim, mas uma escolha).

    Com IA generativa via "prompt após prompt", a duplicação virou silenciosa. O fluxo típico:

    1. Dev pede ao LLM: "escreve uma função que calcula desconto baseado em tier do cliente"
    2. LLM gera função nova, sem consultar a base existente
    3. Dev cola, ajusta, commita

    Se a base de código tem modularização clara e tipagem forte, o LLM consegue (às vezes) identificar que uma função similar já existe e reutilizá-la. Mas se a base é bagunçada — nomes inconsistentes, ausência de tipos, sem indicação clara de onde a regra de negócio vive — o LLM gera nova implementação.

    O resultado: duplicação acelerada. Cada prompt pode virar uma nova cópia. E, como a IA é rápida, o time produz mais código e mais cópias por dia.

    A boa notícia: a solução é a mesma de sempre. Modularização e tipagem rigorosa. A diferença é que agora o ROI é maior — código bem estruturado faz a IA trabalhar com você; código bagunçado faz a IA acelerar a degradação.

    DRY vs WET — o princípio operacional

    A engenharia clássica formaliza isso com DRY (Don't Repeat Yourself): cada pedaço de conhecimento tem uma representação única e autoritativa no sistema. Toda mudança na regra de negócio ocorre em um único lugar.

    O oposto é o WET (Write Everything Twice) — cada uso reimplementa a lógica.

    — Anti-padrão
    WET
    Write Everything Twice
    • ManutençãoAlta e arriscada (múltiplos pontos de falha)
    • BugsDifícil de localizar (erros espalhados, cópias ocultas)
    • IABaixa (cria redundâncias por falta de contexto)
    • AgilidadeReduzida pelo medo na base de código
    • ArquiteturaEntropia alta
    + Princípio
    DRY
    Don't Repeat Yourself
    • ManutençãoSimples (alteração centralizada)
    • BugsFacilitada (lógica única e autoritativa)
    • IAAlta (identifica e reutiliza módulos existentes)
    • AgilidadeElevada por familiaridade e segurança
    • Arquitetura"Casinhas" definidas
    § 5 Nuance

    DRY tem uma nuance: aplicar de forma fanática (todo trecho de duas linhas vira uma função) gera abstração precoce, que é outro tipo de complexidade. A regra prática que funciona: três cópias = refatorar. Dois pode ser coincidência; três é padrão.

    O que fazer agora
    Plano operacional · 5 passos
    1. 1Rode Clone Detection no seu repo hoje. PMD/CPD, jscpd ou a plataforma SQA — escolha a que melhor se integra ao seu stack.
    2. 2Configure threshold operacional. Ponto de partida comum: alertar sobre blocos duplicados com 50+ tokens e 3+ cópias.
    3. 3Triagem por código quente. Não tente desduplicar tudo. Foque nas duplicações em código que muda com frequência (use git log --since para identificar).
    4. 4Refatoração coordenada. Para cada conjunto de cópias: definir versão autoritativa, criar testes, migrar usos um por um.
    5. 5Estabeleça baseline. Não introduza novas duplicações em PRs novos, mesmo aceitando o backlog atual.
    Resumo · Pontos-chave
    Cinco frases para levar embora.
    • →Code Duplication é a replicação de comportamento em múltiplos pontos do sistema.
    • →Diferentemente das outras métricas, o problema é espalhado, não agrupado. Sem epicentro.
    • →Falha oculta é o risco real — você corrige uma cópia; o bug continua nas outras.
    • →IA generativa acelerou o problema. Sem modularização e tipagem, LLMs produzem novas cópias em vez de reutilizar.
    • →DRY como princípio operacional, sem fanatismo. Regra prática: três cópias = refatorar.
    Próximo passo

    Você leu cinco posts sobre métricas individuais. Cada uma com seu mecanismo, seu sintoma, sua remediação. O último post da série fecha a virada: por que olhar todas juntas importa mais do que olhar uma por vez — e como o método SQA estrutura essa visão integrada para diagnóstico cirúrgico.

    Qualidade de código - Método SQA→

    How Codurance can help

    A Codurance acompanha times de engenharia que querem instrumentar a saúde do código sem virar gestores. Ajudamos Tech Leads e Staff Engineers a integrar Clone Detection em pipelines, definir estratégias de refatoração coordenada para conjuntos de cópias e estabelecer arquiteturas que mantêm a base limpa mesmo sob aceleração de IA generativa.

    Se você quer aplicar essas práticas no seu time, entre em contato hoje.