Aikido

Como eliminar duplicação de código: reduzindo a dívida técnica

Bug de lógica

Regra
Eliminar óbvio dentro do ficheiro duplicação.
O código código blocos aumentam a manutenção
manutenção e o risco de incoerência actualizações inconsistentes.
Idiomas suportados: 45+

Introdução

Código copiado e colado dentro de um único arquivo cria pesadelos de manutenção que se agravam com o tempo. Quando a mesma lógica aparece em vários lugares, correções de bugs e atualizações de recursos devem ser aplicadas a todas as ocorrências. Os desenvolvedores inevitavelmente perdem um dos duplicados, levando a um comportamento inconsistente onde a mesma operação produz resultados diferentes dependendo do caminho de código que é executado. Essa inconsistência é difícil de depurar porque a lógica duplicada parece idêntica à primeira vista, e as diferenças só surgem após uma comparação cuidadosa.

Por que isso importa

Propagação de bug: Quando um bug existe em código duplicado, corrigi-lo em um local não o corrige em todos os lugares. Desenvolvedores corrigem a primeira ocorrência sem perceber que cópias existem em outros lugares, deixando o bug ativo sob diferentes condições.

Carga de manutenção: Cada bloco duplicado dobra o custo de manutenção. Alterar a lógica requer encontrar e atualizar cada cópia, e à medida que os arquivos crescem, rastrear duplicatas se torna mais difícil.

Exemplos de código

❌ Não-conforme:

class OrderProcessor {
    async processStandardOrder(order) {
        if (!order.items || order.items.length === 0) {
            throw new Error('Order must have items');
        }
        const total = order.items.reduce((sum, item) => 
            sum + (item.price * item.quantity), 0);
        const tax = total * 0.08;
        const finalAmount = total + tax;
        return { total: finalAmount, tax };
    }
    
    async processExpressOrder(order) {
        if (!order.items || order.items.length === 0) {
            throw new Error('Order must have items');
        }
        const total = order.items.reduce((sum, item) => 
            sum + (item.price * item.quantity), 0);
        const tax = total * 0.08;
        const expressfee = 15.99;
        const finalAmount = total + tax + expressFee;
        return { total: finalAmount, tax, expressFee };
    }
}

Por que está errado: A lógica de validação e o cálculo total são duplicados. Se a taxa de imposto mudar ou a validação precisar de aprimoramento, ambos os métodos exigirão atualizações. Um desenvolvedor pode atualizar o cálculo do imposto em um método, mas esquecer o outro, causando preços inconsistentes.

✅ Compatível:

class OrderProcessor {
    validateOrder(order) {
        if (!order.items || order.items.length === 0) {
            throw new Error('Order must have items');
        }
    }
    
    calculateSubtotal(items) {
        return items.reduce((sum, item) => 
            sum + (item.price * item.quantity), 0);
    }
    
    calculateTax(amount) {
        return amount * 0.08;
    }
    
    async processStandardOrder(order) {
        this.validateOrder(order);
        const subtotal = this.calculateSubtotal(order.items);
        const tax = this.calculateTax(subtotal);
        return { total: subtotal + tax, tax };
    }
    
    async processExpressOrder(order) {
        this.validateOrder(order);
        const subtotal = this.calculateSubtotal(order.items);
        const tax = this.calculateTax(subtotal);
        const expressFee = 15.99;
        return { total: subtotal + tax + expressFee, tax, expressFee };
    }
}

Por que isso importa: A lógica de validação, cálculo e impostos é centralizada em métodos únicos. Alterar a alíquota de imposto significa modificar um único método, e não procurar por duplicatas no arquivo. Cada método auxiliar pode ser testado independentemente, e ambos os tipos de pedido herdam automaticamente quaisquer melhorias ou correções de bugs.

Conclusão

A duplicação dentro do arquivo é frequentemente a mais fácil de corrigir e oferece benefícios imediatos. Extraia a lógica duplicada para funções ou métodos auxiliares assim que você notar o padrão. A regra dos três sugere que, uma vez que o código aparece três vezes, é hora de refatorar. Não espere que a duplicação se espalhe por todo o arquivo antes de abordá-la.

FAQs

Dúvidas?

Quanta duplicação é aceitável antes de refatorar?

A regra dos três é uma boa diretriz: uma vez que um código similar aparece três vezes, extraia-o. No entanto, use o bom senso. Dois blocos duplicados complexos podem justificar uma extração imediata, enquanto três declarações de variáveis simples podem não. Considere a probabilidade de mudança e o custo da inconsistência. Lógicas críticas de segurança ou regras de negócio complexas devem ser desduplicadas imediatamente.

E se o código duplicado tiver pequenas variações?

Parametrize as diferenças. Se dois blocos de código diferem apenas nos valores das variáveis, passe-os como parâmetros para uma função compartilhada. Se o fluxo lógico diferir ligeiramente, use o padrão strategy ou parâmetros opcionais com valores padrão sensatos. Às vezes, a duplicação com diferenças claras é melhor do que uma abstração complexa que obscurece a intenção, então equilibre os princípios DRY com a legibilidade.

Devo extrair duplicação mesmo que isso torne o código mais longo?

Geralmente, sim. Uma função com um nome descritivo geralmente esclarece a intenção melhor do que o código duplicado inline, mesmo que a contagem total de linhas aumente. Os benefícios da manutenção em um único ponto superam as preocupações com a brevidade. No entanto, se a extração criar uma indireção excessiva onde a leitura do código exige saltar por múltiplas chamadas de função, reconsidere se a abstração é apropriada.

Como identificar código duplicado em arquivos grandes?

Procure por padrões de copiar e colar como condições `if` repetidas, loops idênticos ou estruturas de função semelhantes. Muitas IDEs destacam a duplicação estrutural. Durante a revisão de código, se você vir código familiar ao ler um arquivo, procure por ele. A inspeção manual é frequentemente a mais rápida para duplicação dentro do arquivo. Ao refatorar, comece com as duplicatas mais óbvias que aparecem próximas no arquivo.

E quanto ao código de tratamento de erro duplicado?

Extraia o tratamento de erros para funções reutilizáveis ou utilize padrões de decorators/middleware. Se múltiplas funções compartilham a mesma estrutura try-catch com log de erros e transformação idênticos, essa é uma duplicação que vale a pena eliminar. Crie utilitários de tratamento de erros que encapsulem operações com logging consistente, retentativas ou comportamento de fallback, e então utilize esses utilitários em vez de repetir a lógica de tratamento de erros.

Vale a pena refatorar a duplicação em código legado que não estou alterando ativamente?`

Aplique a regra do escoteiro: deixe o código mais limpo do que o encontrou, mas não refatore o código que você não está tocando. Se você estiver modificando uma função e notar duplicação no mesmo arquivo, corrija-a como parte da sua alteração. Não crie grandes PRs de refatoração para código legado, a menos que a dívida técnica esteja bloqueando novos recursos. A melhoria incremental durante o desenvolvimento normal é mais sustentável.

Como evitar a duplicação em primeiro lugar?

Antes de copiar e colar código, pergunte se você não deveria extrair uma função. Durante a revisão de código, sinalize padrões duplicados e solicite a extração. Estabeleça convenções de equipe que desencorajem a duplicação, como exigir funções auxiliares para operações repetidas mais de duas vezes. Use listas de verificação de revisão de código que procurem especificamente por duplicação. A prevenção é mais fácil do que a remediação.

Fique seguro agora

Proteja seu código, Cloud e runtime em um único sistema centralizado.
Encontre e corrija vulnerabilidades rapidamente de forma automática.

Não é necessário cartão de crédito | Resultados da varredura em 32 segundos.