Aikido

Come eliminare la duplicazione del codice: ridurre il debito tecnico

Bug logico

Regola
Elimina le all'interno dello stesso file duplicazioni evidenti
Codice codice blocchi aumentano onere
onere e il rischio di aggiornamenti aggiornamenti.
Lingue supportate: 45+

Introduzione

Il codice copiato e incollato all’interno di un singolo file crea incubi di manutenzione che si aggravano col passare del tempo. Quando la stessa logica compare in più punti, le correzioni di bug e gli aggiornamenti delle funzionalità devono essere applicati a ogni occorrenza. Gli sviluppatori inevitabilmente tralasciano uno dei duplicati, causando un comportamento incoerente in cui la stessa operazione produce risultati diversi a seconda del percorso di codice eseguito. Questa incoerenza è difficile da risolvere perché la logica duplicata sembra identica a prima vista, e le differenze emergono solo dopo un attento confronto.

Perché è importante

Propagazione dei bug: quando un bug è presente in codice duplicato, correggerlo in un punto non significa correggerlo ovunque. Gli sviluppatori risolvono la prima occorrenza senza rendersi conto che esistono copie altrove, lasciando il bug attivo in condizioni diverse.

Onere di manutenzione: ogni blocco duplicato raddoppia i costi di manutenzione. Modificare la logica richiede di individuare e aggiornare ogni copia e, con l'aumentare delle dimensioni dei file, diventa sempre più difficile tenere traccia dei duplicati.

Esempi di codice

❌ Non 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 };
    }
}

Perché è sbagliato: la logica di convalida e il calcolo del totale sono duplicati. Se l'aliquota fiscale cambia o la convalida deve essere migliorata, entrambi i metodi richiedono aggiornamenti. Uno sviluppatore potrebbe aggiornare il calcolo dell'imposta in un metodo ma dimenticarsi dell'altro, causando incongruenze nei prezzi.

✅ Conforme:

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 };
    }
}

Perché è importante: la convalida, il calcolo e la logica fiscale sono centralizzati in singoli metodi. Modificare l’aliquota fiscale significa modificare un solo metodo, senza dover cercare i duplicati in tutto il file. Ogni metodo di supporto può essere testato in modo indipendente, ed entrambi i tipi di ordine ereditano automaticamente eventuali miglioramenti o correzioni di bug.

Conclusione

Le duplicazioni all'interno di un singolo file sono spesso le più facili da correggere e offrono vantaggi immediati. Non appena si individua uno schema ricorrente, è bene estrarre la logica duplicata in funzioni o metodi di supporto. La “regola del tre” suggerisce che, quando un codice ricorre tre volte, è il momento di procedere alla rifattorizzazione. Non bisogna aspettare che la duplicazione si diffonda in tutto il file prima di intervenire.

Domande frequenti

Hai delle domande?

Qual è il livello di duplicazione accettabile prima di procedere alla rifattorizzazione?

La regola del tre è una buona linea guida: quando un codice simile ricorre tre volte, è opportuno estrarlo. Tuttavia, occorre usare il buon senso. Due blocchi complessi duplicati potrebbero giustificare un’estrazione immediata, mentre tre semplici dichiarazioni di variabili potrebbero non richiederla. È importante valutare la probabilità di modifiche e il costo delle incongruenze. La logica critica per la sicurezza o le regole aziendali complesse dovrebbero essere eliminate immediatamente.

E se il codice duplicato presentasse piccole variazioni?

Parametrizza le differenze. Se due blocchi di codice differiscono solo per i valori delle variabili, passali come parametri a una funzione condivisa. Se il flusso logico differisce leggermente, utilizza il pattern “strategia” o parametri opzionali con valori predefiniti ragionevoli. A volte la duplicazione con differenze evidenti è preferibile a un’astrazione complessa che oscura l’intento; cerca quindi di trovare un equilibrio tra i principi DRY e la leggibilità.

Dovrei eliminare i duplicati anche se ciò comporta un aumento della lunghezza del codice?

Di solito sì. Una funzione con un nome descrittivo spesso chiarisce meglio l'intento rispetto al codice duplicato inline, anche se il numero totale di righe aumenta. I vantaggi della manutenzione da un unico punto superano le preoccupazioni relative alla concisione. Tuttavia, se l'estrazione crea un'indirezione eccessiva, per cui la lettura del codice richiede di passare attraverso più chiamate di funzione, è opportuno riconsiderare se l'astrazione sia appropriata.

Come posso individuare il codice duplicato in file di grandi dimensioni?

Cerca schemi di copia-incolla come condizioni "if" ripetute, cicli identici o strutture di funzioni simili. Molti IDE evidenziano le duplicazioni strutturali. Durante la revisione del codice, se mentre leggi un file noti del codice che ti sembra familiare, cercalo. L'ispezione manuale è spesso il metodo più veloce per individuare le duplicazioni all'interno dello stesso file. Quando esegui il refactoring, inizia dalle duplicazioni più evidenti che compaiono vicine tra loro nel file.

E che dire del codice duplicato per la gestione degli errori?

Estraete la gestione degli errori in funzioni riutilizzabili oppure utilizzate decoratori o modelli di middleware. Se più funzioni condividono la stessa struttura try-catch con registrazione e trasformazione degli errori identiche, si tratta di una duplicazione che vale la pena eliminare. Create utilità per la gestione degli errori che incornicino le operazioni con una registrazione coerente, tentativi di ripetizione o comportamenti di fallback, quindi utilizzate tali utilità invece di ripetere la logica di gestione degli errori.

Vale la pena rifattorizzare le duplicazioni nel codice legacy che non sto modificando attivamente?`

Segui la regola dei boy scout: lascia il codice più pulito di come l’hai trovato, ma non rifattorizzare il codice che non stai modificando. Se stai modificando una funzione e noti una duplicazione all’interno dello stesso file, correggila nell’ambito della tua modifica. Non creare pull request di rifattorizzazione di grandi dimensioni per il codice legacy, a meno che il debito tecnico non stia ostacolando lo sviluppo di nuove funzionalità. Il miglioramento incrementale durante il normale sviluppo è più sostenibile.

Come posso evitare fin dall'inizio che si verifichino duplicazioni?

Prima di copiare e incollare il codice, chiediti se non sia invece opportuno estrarne una funzione. Durante la revisione del codice, segnala i pattern duplicati e richiedi la loro estrazione. Stabilisci delle convenzioni di squadra che scoraggino la duplicazione, ad esempio richiedendo l’uso di funzioni di supporto per le operazioni ripetute più di due volte. Utilizza liste di controllo per la revisione del codice che individuino specificatamente le duplicazioni. Prevenire è più facile che rimediare.

Metti in sicurezza ora

Metti in sicurezza il tuo codice, il cloud e il runtime in un unico sistema centralizzato.
Trova e risolvi le vulnerabilità rapidamente e automaticamente.

Nessuna carta di credito richiesta | Risultati della scansione in 32 secondi.