Injection de dépendances en C++ : un guide simple pour débutants

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 à l'injection de dépendances en C++



Lorsque vous commencez tout juste à apprendre le C++, vous écrivez des programmes simples où les classes créent leurs dépendances directement. Par exemple, la classe Car crée elle-même l'objet Engine. Cela fonctionne pour les petits projets, mais lorsque le code s'agrandit, cette approche entraîne de sérieux problèmes : le code devient fortement couplé, difficile à tester et à modifier.



L'injection de dépendances (DI) est un patron de conception dans lequel un objet reçoit ses dépendances de l'extérieur, plutôt que de les créer lui-même. C'est l'un des principes clés du SOLID, plus précisément le principe d'inversion des dépendances (Dependency Inversion Principle).



Dans cet article, nous allons voir ce qu'est l'injection de dépendances en C++, pourquoi elle est nécessaire et comment l'appliquer en pratique. Vous verrez comment ce patron rend le code flexible, testable et maintenable.



Pourquoi sans DI c'est mauvais : le problème du couplage fort



Imaginez que vous écrivez un système de gestion de maison intelligente. Il y a une classe SmartLight qui contrôle une ampoule. Dans une implémentation naïve, elle crée elle-même l'objet Bulb :



#include <iostream>#include <string>

class Bulb {public: void turnOn() { std::cout << "Ampoule allumée"; } void turnOff() { std::cout << "Ampoule éteinte"; }};

class SmartLight {private: Bulb bulb; // Dépendance fortepublic: void activate() { bulb.turnOn(); } void deactivate() { bulb.turnOff(); }};

int main() { SmartLight light; light.activate(); return 0;}


Quels sont les problèmes ici ?



  • Couplage fort : SmartLight est indissociable de Bulb. Si vous voulez utiliser une autre ampoule (par exemple, une LED intelligente ou Phillips Hue), vous devez modifier le code de la classe.
  • Difficulté de test : Vous ne pouvez pas remplacer la vraie ampoule par un "simulacre" (mock) dans les tests unitaires.
  • Violation du SRP : La classe SmartLight fait deux choses : contrôler l'ampoule et la créer.


C'est un exemple classique de couplage fort (tight coupling), que l'injection de dépendances vise à éliminer.



Qu'est-ce que l'injection de dépendances en C++ : concepts de base



L'injection de dépendances (DI) est une technique par laquelle un objet reçoit ses dépendances (généralement via le constructeur, un setter ou une interface) d'une source externe, plutôt que de les créer lui-même. L'idée principale : "Ne demande pas ce dont tu as besoin — on te le donnera".



En C++, la DI est implémentée via :



  • Interfaces (classes abstraites) : Les dépendances sont déclarées via des types abstraits, et non des classes concrètes.
  • Constructeur avec paramètres : Les dépendances sont transmises via le constructeur (méthode la plus courante).
  • Setters : Les dépendances sont définies après la création de l'objet.
  • Conteneurs de dépendances : Des bibliothèques spécialisées qui créent et injectent automatiquement les dépendances (par exemple, boost.di).


Réécrivons l'exemple de la lumière intelligente en utilisant la DI :



#include <iostream>#include <memory>

// Interface abstraite pour l'ampouleclass IBulb {public: virtual void turnOn() = 0; virtual void turnOff() = 0; virtual ~IBulb() = default;};

// Implémentation concrète : ampoule ordinaireclass Bulb : public IBulb {public: void turnOn() override { std::cout << "Ampoule allumée"; } void turnOff() override { std::cout << "Ampoule éteinte"; }};

// Autre implémentation : ampoule LEDclass LedBulb : public IBulb {public: void turnOn() override { std::cout << "Ampoule LED allumée"; } void turnOff() override { std::cout << "Ampoule LED éteinte"; }};

Blogs

Book Recommendations