Réusinage du code legacy en C++ : stratégies et exemples

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Réfactorisation du code legacy en C++ : guide étape par étape



Travailler avec du code legacy en C++ est l'une des tâches les plus difficiles, mais inévitables dans la carrière d'un développeur. Le code legacy manque souvent de tests unitaires, contient des nombres magiques, des fuites mémoire et des dépendances complexes. Cependant, la refactorisation de ce code sans risquer de casser le système est possible si l'on suit des stratégies éprouvées. Dans cet article, nous allons analyser les approches clés pour la refactorisation du code legacy C++ avec des exemples pratiques.



1. Préparation : création d'un filet de sécurité



Avant de modifier le code, il est nécessaire de créer un « filet de sécurité » de tests. Pour C++, c'est particulièrement important car les erreurs peuvent entraîner un comportement indéfini ou un plantage du programme.



Étape 1.1 : Tests de caractérisation

Écrivez des tests qui figent le comportement actuel du code, même s'il est incorrect. Utilisez des frameworks comme Google Test ou Catch2.



// Exemple de test de caractérisation pour une fonction legacy#include <gtest/gtest.h>

// Fonction legacy que nous allons refactoriserint calculatePrice(int quantity, float basePrice) { if (quantity > 100) { return static_cast<int>(basePrice * quantity * 0.9); } else { return static_cast<int>(basePrice * quantity); }}

TEST(PriceCalculatorTest, LegacyBehavior) { EXPECT_EQ(calculatePrice(50, 10.0f), 500); EXPECT_EQ(calculatePrice(150, 10.0f), 1350); // 150*10*0.9}


Étape 1.2 : Intégration dans CI/CD

Ajoutez les tests au système d'intégration continue. Cela garantit que les modifications ne casseront pas la logique existante.



2. Stratégie : refactorisation « intelligente » sans douleur



N'essayez pas de tout réécrire d'un coup. Utilisez une approche incrémentale.



2.1. Extraction d'interface (Extract Interface)

Si le code est étroitement lié à des états globaux ou à des classes spécifiques, commencez par extraire des abstractions.



Problème : La classe travaille directement avec le système de fichiers.

// Code legacyclass DataProcessor {public:    void process(const std::string& filename) {        std::ifstream file(filename);        // logique de traitement complexe    }};


Solution : Nous introduisons une interface et l'injection de dépendances.

// Nouvelle interfaceclass IFileReader {public:    virtual std::string read(const std::string& path) = 0;    virtual ~IFileReader() = default;};

// Refactorisationclass DataProcessor {public: explicit DataProcessor(std::unique_ptr<IFileReader> reader) : reader_(std::move(reader)) {} void process(const std::string& filename) { auto data = reader_->read(filename); // logique de traitement }

private: std::unique_ptr<IFileReader> reader_;};


2.2. Remplacement des nombres magiques par des constantes

Le code legacy contient souvent des nombres dont le sens n'est pas clair.



// Avant la refactorisationif (buffer.size() > 4096) {    resizeBuffer(8192);}

// Après la refactorisationconstexpr size_t kMaxBufferSize = 4096;constexpr size_t kResizeTarget = 8192;

if (buffer.size() > kMaxBufferSize) { resizeBuffer(kResizeTarget);}


3. Lutte contre les fuites mémoire et les constructions non sécurisées



Le code legacy C++ utilise souvent des pointeurs bruts et une gestion manuelle de la mémoire. Remplacez-les par des pointeurs intelligents et des wrappers RAII.



3.1. Remplacement de new/delete par std::unique_ptr

// Ancien code (risque de fuite en cas d'exception)void processData() {    Data* data = new Data();    // ... travail avec data ...    delete data;}

// Nouveau code (sécurisé)void processData() { auto data = std::make_unique<Data>(); // ... travail avec data ... // delete n'est pas nécessaire}


3.2. Utilisation de std::vector au lieu de tableaux bruts

//                

Blogs

Book Recommendations