Principes SOLID en C++ : de la théorie à la pratique pour un code propre

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

Introduction : Pourquoi SOLID est important pour le développeur C++ ?

\n\n

SOLID est l'acronyme de cinq principes fondamentaux de la programmation orientée objet, formulés par Robert Martin (Oncle Bob). Pour le développeur C++, ces principes ne sont pas une simple théorie abstraite, mais un outil pratique qui aide à créer des applications flexibles, maintenables et testables. Dans le monde du C++, où la gestion de la mémoire et les performances sont critiques, suivre SOLID permet d'éviter le "code spaghetti" et simplifie le refactoring.

\n\n

Dans cet article, nous analyserons chaque principe SOLID avec des exemples concrets en C++. Vous verrez comment la violation des principes entraîne des problèmes et comment les corriger. Nous utiliserons du C++ moderne (C++11/14/17/20) pour que les exemples soient actuels.

\n\n

1. Single Responsibility Principle (SRP) — Principe de responsabilité unique

\n\n

Essence du principe

\n

Une classe ne doit avoir qu'une seule raison de changer. Autrement dit, chaque classe est responsable d'une seule fonctionnalité ou d'un seul aspect du système.

\n\n

Violation du SRP en C++

\n

Considérons une classe qui viole le SRP : elle gère à la fois les données d'un rapport et son formatage.

\n\n
class Report {\npublic:\n    void generateReport(const std::vector<Data>& data) {\n        // Logique de traitement des données\n        m_data = data;\n    }\n    \n    void saveToFile(const std::string& filename) {\n        // Logique de sauvegarde dans un fichier\n        std::ofstream file(filename);\n        for (const auto& item : m_data) {\n            file << item.toString() << "\\n";\n        }\n    }\n    \n    void printToConsole() {\n        // Logique d'affichage sur la console\n        for (const auto& item : m_data) {\n            std::cout << item.toString() << std::endl;\n        }\n    }\n    \nprivate:\n    std::vector<Data> m_data;\n};
\n\n

Problème : si le format de sortie change, il faudra modifier la classe Report. Si la méthode de stockage des données change, il faudra aussi la modifier. Cela viole le SRP.

\n\n

Correction : séparer les responsabilités

\n\n
// Responsable uniquement des données du rapport\nclass ReportData {\npublic:\n    void addData(const Data& item) {\n        m_data.push_back(item);\n    }\n    \n    const std::vector<Data>& getData() const {\n        return m_data;\n    }\n    \nprivate:\n    std::vector<Data> m_data;\n};\n\n// Responsable uniquement de la sauvegarde\nclass FileSaver {\npublic:\n    void save(const std::string& filename, const ReportData& report) {\n        std::ofstream file(filename);\n        for (const auto& item : report.getData()) {\n            file << item.toString() << "\\n";\n        }\n    }\n};\n\n// Responsable uniquement de l'affichage sur console\nclass ConsolePrinter {\npublic:\n    void print(const ReportData& report) {\n        for (const auto& item : report.getData()) {\n            std::cout << item.toString() << std::endl;\n        }\n    }\n};
\n\n

Maintenant, chaque classe a une seule raison de changer, ce qui rend le code plus flexible et plus facile à tester.

\n\n

2. Open-Closed Principle (OCP) — Principe d'ouverture/fermeture

\n\n

Essence du principe

\n

Les entités logicielles (classes, modules, fonctions) doivent être ouvertes à l'extension, mais fermées à la modification. Cela signifie que vous devez pouvoir ajouter de nouvelles fonctionnalités sans modifier le code existant.

\n\n

Violation du OCP en C++

\n

Imaginez un système de calcul de remises où chaque type de client utilise un if-else.

\n\n
class DiscountCalculator {\npublic:\n    double calculateDiscount(const std::string& customerType, double amount) {\n        if (customerType == "regular") {\n            return amount * 0.1; // 10%\n        } else if (customerType == "vip") {\n            return amount * 0.2; // 20%\n        } else if (customerType == "premium") {\n            return amount * 0.3; // 30%\n        }\n                

Blogs

Book Recommendations