Aikido

Comment éliminer la duplication de code : réduire la dette technique

Bug logique

Règle
Éliminer évidentes à l'intérieur d'un à l'intérieur d'un même fichier.
Le code code blocs augmentent la maintenance
maintenance et et le risque de incohérentes. incohérentes.
Langues prises en charge : 45+

Introduction

Le code copié-collé au sein d'un même fichier engendre des cauchemars de maintenance qui s'aggravent avec le temps. Lorsque la même logique apparaît à plusieurs endroits, les corrections de bugs et les mises à jour de fonctionnalités doivent être appliquées à chaque occurrence. Les développeurs manquent inévitablement l'un des doublons, ce qui entraîne un comportement incohérent où la même opération produit des résultats différents selon le chemin de code exécuté. Cette incohérence est difficile à déboguer car la logique dupliquée semble identique à première vue, et les différences n'apparaissent qu'après une comparaison minutieuse.

Pourquoi c'est important

Propagation des bugs : Lorsqu'un bug existe dans du code dupliqué, le corriger à un endroit ne le corrige pas partout. Les développeurs corrigent la première occurrence sans réaliser que des copies existent ailleurs, laissant le bug actif dans d'autres conditions.

Charge de maintenance : Chaque bloc dupliqué double le coût de maintenance. Modifier la logique nécessite de trouver et de mettre à jour chaque copie, et à mesure que les fichiers augmentent, le suivi des doublons devient plus difficile.

Exemples de code

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

Pourquoi c'est incorrect : La logique de validation et le calcul total sont dupliqués. Si le taux de taxe change ou si la validation nécessite une amélioration, les deux méthodes nécessitent des mises à jour. Un développeur pourrait mettre à jour le calcul de la taxe dans une méthode mais oublier l'autre, entraînant une tarification incohérente.

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

Pourquoi c'est important : La logique de validation, de calcul et de taxation est centralisée dans des méthodes uniques. Modifier le taux d'imposition signifie modifier une seule méthode, plutôt que de chercher des doublons dans le fichier. Chaque méthode d'assistance peut être testée indépendamment, et les deux types de commandes héritent automatiquement de toute amélioration ou correction de bug.

Conclusion

La duplication intra-fichier est souvent la plus facile à corriger et offre des avantages immédiats. Extrayez la logique dupliquée dans des fonctions ou méthodes d'aide dès que vous remarquez le motif. La règle de trois suggère qu'une fois que le code apparaît trois fois, il est temps de refactoriser. N'attendez pas que la duplication se propage dans tout le fichier avant d'y remédier.

FAQ

Des questions ?

Quel niveau de duplication est acceptable avant de refactoriser ?

La règle de trois est une bonne ligne directrice : une fois qu'un code similaire apparaît trois fois, extrayez-le. Cependant, faites preuve de discernement. Deux blocs dupliqués complexes pourraient justifier une extraction immédiate, tandis que trois déclarations de variables simples pourraient ne pas le faire. Tenez compte de la probabilité de changement et du coût de l'incohérence. La logique critique pour la sécurité ou les règles métier complexes devraient être dédupliquées immédiatement.

Que se passe-t-il si le code dupliqué présente de petites variations ?

Paramétrez les différences. Si deux blocs de code ne diffèrent que par les valeurs de leurs variables, passez-les en paramètres à une fonction partagée. Si le flux logique diffère légèrement, utilisez le modèle de stratégie (strategy pattern) ou des paramètres optionnels avec des valeurs par défaut pertinentes. Parfois, la duplication avec des différences claires est préférable à une abstraction complexe qui obscurcit l'intention, il faut donc équilibrer les principes DRY (Don't Repeat Yourself) avec la lisibilité.

Dois-je extraire la duplication même si cela allonge le code ?

Généralement, oui. Une fonction avec un nom descriptif clarifie souvent mieux l'intention qu'un code dupliqué en ligne, même si le nombre total de lignes augmente. Les avantages d'une maintenance en un point unique l'emportent sur les préoccupations de concision. Cependant, si l'extraction crée une indirection excessive où la lecture du code nécessite de naviguer à travers de multiples appels de fonction, il convient de réévaluer si l'abstraction est appropriée.

Comment identifier le code dupliqué dans les fichiers volumineux ?

Recherchez les schémas de copier-coller, tels que les conditions `if` répétées, les boucles identiques ou les structures de fonctions similaires. De nombreux IDEs mettent en évidence la duplication structurelle. Lors d'une revue de code, si vous voyez du code familier en parcourant un fichier, recherchez-le. L'inspection manuelle est souvent la plus rapide pour la duplication au sein d'un même fichier. Lors du refactoring, commencez par les doublons les plus évidents qui apparaissent proches les uns des autres dans le fichier.

Qu'en est-il du code de gestion d'erreurs dupliqué ?

Extrayez la gestion des erreurs dans des fonctions réutilisables ou utilisez des patterns de décorateurs/middleware. Si plusieurs fonctions partagent la même structure try-catch avec une journalisation et une transformation d'erreurs identiques, il s'agit d'une duplication à éliminer. Créez des utilitaires de gestion des erreurs qui encapsulent les opérations avec une journalisation, des tentatives de réessai ou un comportement de repli cohérents, puis utilisez ces utilitaires au lieu de répéter la logique de gestion des erreurs.

Vaut-il la peine de refactoriser les duplications dans du code hérité que je ne modifie pas activement ?

Appliquez la règle du boy-scout : laissez le code plus propre que vous ne l'avez trouvé, mais ne refactorisez pas le code que vous ne touchez pas. Si vous modifiez une fonction et remarquez une duplication dans le même fichier, corrigez-la dans le cadre de votre modification. Ne créez pas de grandes PR de refactoring pour le code hérité, sauf si la dette technique bloque de nouvelles fonctionnalités. L'amélioration incrémentale pendant le développement normal est plus durable.

Comment prévenir la duplication dès le départ ?

Avant de copier-coller du code, demandez-vous si vous ne devriez pas plutôt extraire une fonction. Lors de la revue de code, signalez les motifs dupliqués et demandez leur extraction. Établissez des conventions d'équipe qui découragent la duplication, comme l'exigence de fonctions d'aide pour les opérations répétées plus de deux fois. Utilisez des listes de contrôle de revue de code qui recherchent spécifiquement la duplication. La prévention est plus facile que la remédiation.

Sécurisez-vous maintenant.

Sécuriser votre code, votre cloud et votre runtime dans un système centralisé unique.
Détectez et corrigez les vulnérabilités rapidement et automatiquement.

Pas de carte de crédit requise | Résultats du scan en 32 secondes.