Comprendre les principes SOLID en 5 minutes
Grâce aux banques, aux profs, aux ampoules, au piano, et à la Poste !
Aujourd’hui, entre deux averses, nous avons décidé avec ma copine d’aller nous balader au Parc Monceau à Paris.
C’est un très beau parc, très agréable lorsque le temps s’y prête. Il est à environ une dizaine de minutes de chez moi.
Au moment de partir, elle me dit :
🤷♀️ “ Je t’entends souvent parler en visio de principes solides, qu’est-ce que c’est en fait ?”
🤓 “ Ce sont des principes de programmation pour écrire du code propre, maintenable, évolutif. C’est un acronyme : S.O.L.I.D, une lettre par principe”
Curieuse, elle me répond :
🤷♀️ “Ah d’accord ! Explique-moi, mais sans notion de code !”
Faire comprendre les principes S.O.L.I.D à ma copine le temps d’aller au parc, alors qu’elle n’a jamais coder une seule fois de sa vie ? Il va falloir utiliser des analogies de la vraie vie…
Challenge Accepted 😎 !
Voilà comment je lui ai expliqué :
S : Single Responsibility Principle
J’ai récemment dû changer de banque.
Quand on change de banque, il faut donc mettre fin à tous les virements vers ce compte et transférer les abonnements.
Certains virements sont automatiquement transférés par la banque. Mais pour le reste, il faut le faire tout seul :
L’abonnement à la salle de sport, la carte bancaire préenregistrées un peu partout sur internet, les abonnements Netflix, Deezer, etc.
🤷♀️ “Oui, et alors ?”
Imagine que j’aie une carte de paiement personnel. Lorsque je suis dans la Banque A, je lie donc cette carte à la Banque A. Mais si demain je change et que je passe à la Banque B, j’ai juste à relier maintenant ma carte à la banque B, plus besoin de modifier partout mes abonnements puisque c’est la même carte !
La carte a donc “la responsabilité” d’assurer le paiement pour la personne Pierre Criulanscy. La seule raison valable pour laquelle elle devrait être modifiée sur un site quelconque, c’est si je décidais que ça soit quelqu’un d’autre qui paye !
Avec ma carte bancaire classique, la “responsabilité” de paiement peut changer même si c’est toujours moi qui paye, mais que je doive changer de banque et donc modifier la carte. On dit donc que le Single Responsibility Principle est violé.
En code, le Single Responsibility Principle se définit de la façon suivante : un module / une classe ne doit avoir qu’une seule raison de changer.
Open-Closed Principle
C’est mon principe préféré ! Il est tellement évident dans la vie de tous les jours que c’est étonnant de se rendre compte qu’on peut le violer si facilement dans le code !
Imagine que tu sois professeure dans un collège. Il existe dans la salle des profs une armoire de fournitures.
Dans cette armoire se trouve un tiroir où sont stockés les stylos rouges.
🤷♀️ “Ok, jusque-là rien de compliqué.”
En effet ! Tu vas prendre dans le tiroir un stylo rouge pour corriger une copie dès que tu en as besoin, sans même regarder dans le tiroir.
Seulement voilà, un collègue décide d’utiliser des stylos verts pour corriger ses copies ! Il décide donc d’ajouter dans le même tiroir les stylos verts !
🤷♀️ “Pas pratique… Du coup maintenant je suis obligée de regarder dans le tiroir quand je prends un stylo pour être sûr que j’ai bien pris un stylo rouge et pas un vert…”
Exactement ! Car ton collègue à “modifier” le contenu du tiroir.
🤷♀️ “Il aurait simplement dû mettre ses stylos dans un autre tiroir en fait”
C’est ça. Ça parait tellement évident dans la vraie vie. Ce faisant, il a violé le Open-Closed Principle qui, appliqué à l’armoire, stipulerait que celle-ci doit pouvoir accueillir d’autres tiroirs si on doit avoir d’autres fournitures, mais qu'on ne doit pas modifier le contenu des tiroirs pour y ajouter des fournitures différentes.
Dans le code, le Open-Closed Principle stipule donc qu’un module ou une classe, doit être ouvert à l’extension, mais fermé à la modification.
Liskov Substitution Principle
Ce principe va être beaucoup plus complexe à expliquer simplement… Mais je vais tout de même essayer !
Tu es dans ton appartement, tu allumes la lumière puis…pouf ! Plus de lumière, l’ampoule a grillé. Tu étais censée être plongée dans une lumière chaude et réconfortante, et te voilà dans le noir complet.
Ni une ni deux, tu te rends à la quincaillerie la plus proche pour acheter une ampoule avec le même culot.
Tu dis au vendeur que tu as besoin d’une ampoule pour remplacer la tienne. Il te répond :
👨🔧 “Alors je n’ai plus d’ampoule classique, il ne me reste que ces ampoules, c’est le bon culot, mais c’est une gamme un peu spéciale je vous préviens !”
Sans vraiment prêter attention à la remarque du vendeur, tu vérifies que le culot est le bon, tu achètes les ampoules, et tu rentres chez toi.
Tu remplaces l’ampoule, tu allumes… Mais ton appartement devient un véritable caléidoscope ! Tu viens de comprendre ce que le vendeur voulait dire par “gamme spéciale”. Les ampoules que tu as achetées sont en fait des ampoules fantaisies à motifs, projetant ainsi sur les murs de ton appartement tout un tas d’images farfelues.
🤷♀️ “C’est le moment où tu me dis que le Liskov Subsitution Principle a donc été violé c’est ça ?”
Complètement !
En achetant une ampoule, tu t’attendais à ce qu’elle adopte un certain comportement : éclairer ton appartement de façon homogène.
La seule condition pour apporter ce comportement était donc que l’ampoule respecte le “contrat” d’avoir le bon culot.
Tu as donc “substitué” l’ancienne ampoule par la nouvelle, en respectant le “contrat” imposé par la douille de ta lampe : avoir le bon culot.
Le fait que le contrat soit respecté, mais que le comportement soit totalement différent est donc une violation du Liskov Substition Principle !
Dans le code, on dit que que si l’on substitue un objet parent par un objet enfant et que celui-ci change le comportement de façon totalement innatendue, alors le Liskov Substitution Principle est violé.
Interface Segregation Principle
Je viens d’acheter un appartement, actuellement j’ai un piano numérique dont j’ai simplement acheté un support basique.
🤷♀️ “Oui, tu m’as dit que tu aimerais profiter de l’emménagement dans ton nouvel appartement pour acheter un vrai meuble pour y loger ton piano numérique :)”
Oui, c’est plus joli :)
Mettons donc que je veuille acheter ce fameux meuble pour mon piano. Je me rends chez le vendeur, et celui-ci me dit :
🧑💼 “Un meuble pour votre piano électrique ? Oui bien sûr monsieur ! Ce sera 800€ !”
🤓 “800€ ? Mais le piano m’a coûté 650€, comment le meuble support peut-il être plus cher que le piano ?”
🧑💼 “Non mais monsieur nous vous vendons le piano, avec son meuble et ses pédales”
🤓 “Mais je n’ai besoin que du meuble et des pédales ! J’ai déjà le piano !”
🧑💼 “Eh bien c’est pas grave, vous n’utiliserez que le meuble, c’est tout !”
…
🤷♀️ “C’est complètement idiot…”
Oui, totalement ! Je veux uniquement le meuble, mais je me retrouve avec le piano en double. L’Interface Segregation Principle est donc violé, dans le sens où pour obtenir ce que je veux, je dois embarquer beaucoup plus que ce dont j’ai besoin, sans l’utiliser !
Dans le code, ce principe stipule qu’aucun client ne devrait dépendre de méthodes qu’il n’utilise pas.
Dependency Inversion Principle
Tu dois envoyer un colis à un ami qui se trouvent à l’étranger.
Pour ce faire, tu vas donc avoir besoin de faire appel aux services de la Poste.
🤷♀️ “Oui, assez classique pour l’instant.”
Ton ami habite en Amérique donc tu te rends à l’aéroport le plus proche en demandant où se trouve l’avion de la Poste. Logique non ? A priori, c’est le moyen le plus rapide pour franchir l’océan.
🤷♀️ “Bah non pas logique, je vais juste au bureau de Poste en fait”
Évidemment que c’est ce que tu ferais ! En allant directement à l’aéroport tu violes le Dependency Inversion Principle.
Ce principe stipule que lorsque tu délègues un comportement, comme ici à la Poste par exemple, tu ne dois pas dépendre d’un moyen concret, mais plutôt d’un simple “contrat”.
Le “contrat” que tu as avec la Poste c’est : “voici mon colis, contentez-vous de l’envoyer pour que mon ami le reçoive”. Le moyen concret d’y parvenir ça va être par exemple par avion, par train, par bateau, etc.,
Ce n’est pas à toi de “dépendre” directement de l’avion de la Poste dans cet exemple.
La Poste décide de remplir son contrat, en utilisant l’avion, mais pour toi, c’est transparent !
En code, le Dependency Inversion Principle stipule qu’un module de haut niveau ne doit pas dépendre d’un module de base niveau, les deux doivent dépendre d’abstractions. Et ces abstractions ne doivent pas dépendre des détails, mais les détails doivent dépendre des abstractions.
👩 “Trop bien j’ai compris ! On arrive justement au Parc, allez viens, on va manger une crêpe !”
🤓 “Tiens d’ailleurs, c’est marrant, les différentes garnitures de crêpes, c’est un peu comme le pattern Decorator……”
…
Merci Léa pour l’inspiration ❤️
Happy Coding :)
Cet article vous a plu ? Vous pouvez me soutenir gratuitement en vous inscrivant à mon programme de parrainage, en échange, je vous offre des bons de réduction valables à vie sur tous les cours (actuels et futurs) de CraftAcademy.fr 🎉