Principes SOLID en C++ : théorie et pratique de A à Z

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

Principes SOLID en C++ : théorie et pratique de A à Z



SOLID est un acronyme désignant cinq principes fondamentaux de la programmation orientée objet et de la conception, formulés par Robert Martin (également connu sous le nom de "Uncle Bob"). Pour C++, ces principes sont particulièrement importants car ils permettent de créer un code flexible, maintenable et testable, facile à faire évoluer. Dans cet article, nous analyserons chaque principe d'un point de vue théorique et le soutiendrons par des exemples pratiques en C++.



Qu'est-ce que SOLID et pourquoi en a-t-on besoin ?

SOLID est un ensemble de règles qui aident le développeur à éviter le "mauvais" code. Le respect de ces principes conduit à une réduction du couplage et à une augmentation de la cohésion des modules. En C++, où les puissantes capacités des templates et l'héritage multiple peuvent facilement mener au chaos, SOLID sert de boussole fiable. Chaque lettre de l'acronyme se décode comme suit :

  • S — Single Responsibility Principle (Principe de responsabilité unique)
  • O — Open-Closed Principle (Principe d'ouverture/fermeture)
  • L — Liskov Substitution Principle (Principe de substitution de Barbara Liskov)
  • I — Interface Segregation Principle (Principe de ségrégation des interfaces)
  • D — Dependency Inversion Principle (Principe d'inversion des dépendances)


Principe de responsabilité unique (Single Responsibility)

Théorie : Une classe ne doit avoir qu'une seule raison de changer. Autrement dit, une classe ne doit être responsable que d'une seule partie de la fonctionnalité du programme.

Pratique en C++ : La violation de ce principe conduit souvent à des "objets divins" qui font tout à la fois.

// ❌ Mauvais : la classe viole le SRPclass Report {public:    void generateReport() { /* génération des données */ }    void saveToFile(const std::string& filename) { /* écriture dans un fichier */ }    void printReport() { /* envoi à l'imprimante */ }};

// ✅ Bon : on sépare les responsabilitésclass ReportData {public: std::string generate() { return "Données du rapport"; }};

class ReportSaver {public: void save(const std::string& data, const std::string& filename) { std::ofstream file(filename); file << data; }};

class ReportPrinter {public: void print(const std::string& data) { /* impression */ }};

Dans le bon exemple, chaque classe est responsable de sa propre tâche. Cela simplifie les tests et la modification du code.



Principe d'ouverture/fermeture (Open-Closed)

Théorie : Les entités logicielles (classes, modules, fonctions) doivent être ouvertes à l'extension, mais fermées à la modification.

Pratique en C++ : On y parvient grâce à l'abstraction et au polymorphisme.

// ❌ Mauvais : pour ajouter une nouvelle forme, il faut modifier le codeclass AreaCalculator {public:    double calculateArea(std::string shapeType, double param) {        if (shapeType == "circle") {            return 3.14 * param * param;        } else if (shapeType == "square") {            return param * param;        }        return 0.0;    }};

// ✅ Bon : on utilise le polymorphismeclass Shape {public: virtual double area() const = 0; virtual ~Shape() = default;};

class Circle : public Shape { double radius;public: Circle(double r) : radius(r) {} double area() const override { return 3.14159 * radius * radius; }};

class Square : public Shape { double side;public: Square(double s) : side(s) {} double area() const override { return side * side; }};

class AreaCalculatorOCP {public: double calculate(const Shape& shape) { return shape.area(); }};

Maintenant, pour ajouter une nouvelle forme (par exemple, un triangle), il n'est pas nécessaire de modifier A

Blogs

Book Recommendations