L'injection de dépendances
Notions théoriques
L'injection de dépendances est un patron de conception qui permet de rendre nos applications plus modulaires, plus testables et plus maintenables.
Au lieu de créer des objets à l'intérieur d'une classe ou d'une méthode, nous les passons en tant que paramètres (on "injecte" les dépendances).
Dans notre jeu de combat, par exemple, nous pourrions avoir une classe
Gamequi dépend d'une classeFighter. Au lieu de créer un objetFighterà l'intérieur de la classeGame, nous pourrions le passer en paramètre à la méthodestartGame.
Pourquoi utiliser l'injection de dépendances ?
- Cela nous permet de changer les détails de ces objets sans avoir à modifier la classe ou la méthode qui les utilise.
Car elle se base sur le principe de l'inversion de contrôle.
- De plus, cela facilite les tests unitaires, car vous pouvez injecter des fausses données (mocks) pour tester la classe indépendamment de ses dépendances réelles.
Qu'est-ce que l'inversion de contrôle ?
Cela signifie que ce n'est pas la classe qui contrôle comment et quand créer ses dépendances, mais c'est une entité externe (généralement un conteneur d'injection de dépendances) qui s'en charge.
Par exemple, disons que vous avez une classe Game qui utilise un objet Fighter.
Si Game crée l'objet Fighter directement,
alors chaque fois que vous voulez changer quelque chose sur Fighter
(par exemple, changer les paramètres du constructeur),
vous devez également modifier Game.
En revanche, si Game reçoit un objet Fighter par injection de dépendances
(c'est-à-dire qu'un objet Fighter est passé au constructeur de Game),
alors Game n'a pas besoin de savoir comment Fighter est créé.
Cela signifie que vous pouvez changer Fighter comme vous le souhaitez, sans avoir à modifier Game.
L'injection de dépendances rend votre code plus flexible et plus facile à maintenir, car les modifications d'une partie du code n'entraînent pas nécessairement des modifications dans d'autres parties.
Exemple pratique
class Fighter {
public function attack() {
// Code pour attaquer
}
}
class Game {
private $fighter;
public function __construct(Fighter $fighter) {
$this->fighter = $fighter;
}
public function startGame() {
// Utiliser $this->fighter pour commencer le jeu
$this->fighter->attack();
}
}
Et maintenant, nous pouvons injecter un objet Fighter dans un objet Game comme ceci :
$fighter = new Fighter();
$game = new Game($fighter);
$game->startGame();
Test de mémorisation/compréhension
TP pour réfléchir et résoudre des problèmes
Dans ce TP, vous allez mettre en pratique l'injection de dépendances dans notre jeu de combat :
- Vous allez créer une nouvelle classe
Arenaqui aura une méthodeopenGates. - Ensuite, vous allez créer une classe
Gamequi reçoit un objetArenaen paramètre de son constructeur.
La classe
Gamedoit avoir une méthodestartGamequi utilise l'objetArenapour commencer le jeu.
Voici les consignes détaillées pour réaliser le TP :
Étape 1 : Création de la classe Arena
Dans cette étape, vous allez créer une classe Arena. Cette classe doit avoir une méthode openGates qui affiche le message "Les portes de l'arène s'ouvrent !".
Pour cela, suivez les étapes suivantes :
- Ouvrez votre éditeur de texte et créez un nouveau fichier PHP que vous nommerez
Arena.php. - Dans ce fichier, déclarez une nouvelle classe appelée
Arena. - Dans la classe
Arena, définissez une méthode publiqueopenGates. - Dans la méthode
openGates, utilisez la fonctionechopour afficher le message "Les portes de l'arène s'ouvrent !".
Votre fichier Arena.php devrait ressembler à ceci :
class Arena {
public function openGates() {
echo "Les portes de l'arène s'ouvrent !\n";
}
}
Étape 2 : Création de la classe Game
Dans cette étape, vous allez créer une classe Game qui reçoit un objet Arena en paramètre de son constructeur. La classe Game doit avoir une méthode startGame qui utilise l'objet Arena pour commencer le jeu.
Suivez ces étapes :
- Créez un nouveau fichier PHP que vous nommerez
Game.php. - Dans ce fichier, déclarez une nouvelle classe appelée
Game. - Dans la classe
Game, définissez un propriété privé$arena. - Définissez un constructeur qui prend un objet
Arenaen paramètre et l'assigne à la propriété$arena. - Définissez une méthode publique
startGamequi appelle la méthodeopenGatesde l'objetArena(la propriété privé$arena).
Étape 3 : Utiliser nos classes
Maintenant que vous avez créé vos classes, il est temps de les utiliser.
- Créez un nouveau fichier PHP que vous nommerez
main.php. - Dans ce fichier, incluez les fichiers
Arena.phpetGame.phpen utilisant la fonctioninclude. - Créez un nouvel objet
Arenaet un nouvel objetGameen passant l'objetArenaau constructeur deGame. - Appelez la méthode
startGamede l'objetGame.
Votre fichier main.php devrait ressembler à ceci :
// main.php
include 'Arena.php';
include 'Game.php';
$arena = new Arena();
$game = new Game($arena);
$game->startGame();
Maintenant, ouvrez votre terminal, naviguez jusqu'au dossier contenant votre fichier main.php et exécutez le fichier avec la commande php main.php.
Vous devriez voir le message "Les portes de l'arène s'ouvrent !" s'afficher dans la console.
Si c'est le cas, félicitations ! Vous avez réussi le TP.
Une solution
Vous devez être connecté pour voir le contenu.