Le principe d’inversion des dépendances a toujours l’air plus compliqué qu’il ne l’est réellement. Il dit que :
Les classes de haut niveau ne doivent pas avoir à changer juste parce que les classes de bas niveau changent.
Les classes de haut niveau sont les classes qui, habituellement, dirigent votre système. Elles doivent rester aussi stables que possible.
Pourquoi utiliser l’inversion des dépendances ?
Prenons l’exemple des voitures. Les classes de haut niveau sont les éléments avec lesquels vous avez le plus d’interactions : le volant, l’accélérateur, et la pédale de frein. Ils disent aux classes d’implémentation de bas niveau (les pneus, le moteur, et les freins) ce qu’elles doivent faire.
Qu’arrive-t-il aux classes de haut niveau si vous transformez un moteur à essence en moteur électrique ? Rien ! Le conducteur continue à tourner, accélérer et freiner en utilisant les mêmes fonctionnalités. Si vous aviez enfreint ce principe, le passage au moteur électrique (une classe de bas niveau) vous forcerait à changer l’interface (une classe de haut niveau) pour le conducteur. C'est plutôt évident pour une voiture, mais c’est facile à rater dans du code.
Ce principe vous permet de vous assurer que ce sont les classes de haut niveau qui dirigent. Elles définissent l’interface à travers laquelle elles communiquent. Dans la voiture, vous faites accélérer le moteur en appuyant sur l’accélérateur. C’est au moteur de se conformer à ce standard.
Comment appliquer l’inversion des dépendances à notre code ?
Dans notre jeu, la vue doit être « dirigée » par le contrôleur. C’est donc le contrôleur qui définit l’interface. Toute vue doit s’y conformer. Sinon, chaque fois que vous modifiez l’interface, le contrôleur devra être modifié pour se conformer à la vue (ce qui serait fait à l’envers).
Remarquez quand même qu’au chapitre précédent, nous avons dû modifier le contrôleur de façon significative pour pouvoir mettre à niveau la vue, afin qu’elle puisse gérer la diffusion ! Il semblerait donc que nous ne nous conformions pas encore au principe d’inversion des dépendances…
En réalité, la racine de notre problème vient du fait d’avoir donné trop d’informations au contrôleur sur la structure de la vue. Le déroulement du jeu n’est pas affecté par l’existence de différentes diffusions supplémentaires en cours, donc Controller
ne doit pas contenir de code qui dépende de détails spécifiques de la vue.
Essayez par vous-même !
Comme dernier défi, annulons nos modifications à Controller.run
, et trouvons une façon de diffuser notre partie à la télévision sur n’importe quelle quantité de composantes de la vue, sans jamais avoir à modifier le code dans notre contrôleur. Assurez-vous que vous suivez chacun des cinq principes de conception SOLID, ainsi que le design pattern MVC dans votre solution ! Reprenez le code depuis notre dernière modification : lien vers le code.
Je vous donne un indice pour que vous puissiez passer jusqu’à 15 minutes à travailler sur cet exercice avant de voir la solution complète : essayez de définir une nouvelle classe nommée Views
, et passez-la au contrôleur comme unique objet de la vue.
Voici le lien vers le code.
Félicitations, vous avez un jeu de cartes qui fonctionne, et qui sera facile à maintenir toutes les fois où nous devrons ajouter de nouvelles fonctionnalités ! Nous pouvons simplement et directement changer tout aspect du jeu sans trop nous inquiéter de la façon dont nos changements risquent d’impacter d’autres parties de notre code. 😍
C’est le rêve pour écrire du code dans n’importe quel langage : d’avoir confiance en votre code, sachant qu’il est assez SOLID pour qu’un petit changement à un endroit ne provoque de cauchemars pour personne.
En résumé
L’inversion des dépendances dit que les concepts de haut niveau doivent communiquer à travers des abstractions de haut niveau. En d’autres termes : les classes de haut niveau ne doivent pas avoir à changer juste parce que les classes de bas niveau changent.
Soyez attentif à ce que les classes n’en sachent pas trop sur les implémentations des autres classes.
Au chapitre suivant, nous nous pencherons sur plusieurs mauvaises idées ou pièges faciles lorsque l’on code, et nous verrons comment les éviter.