Je souhaiterais vous parler de 2 techniques très simples, qui permettent d’écrire du code plus facile à faire évoluer. L’idée est de respecter le principe d’ouvert-fermé (OCP).
Les techniques
Pour mémoire, le principe OCP dit qu’un morceau de code doit être ouvert aux évolutions, mais fermé aux modifications. Il s’agit donc de pouvoir faire évoluer du code sans toucher directement à ce code. Pour en savoir plus sur les bases du principe, je vous invite à consulter l’article Concevoir des applications SOLID avec OCP.
Habituellement, lorsque vous codez une application, vous écrivez des conditions et des cas avec un nombre assez limité. Vous commencez à écrire une condition (bloc if) et celle-ci à seulement 3 cas possibles (if, else if, else if). Tout se passe bien.
Seulement voilà, un peu plus tard (parfois quelques jours), les spécifications changent et votre responsable vous demande d’ajouter des cas supplémentaires pour cette fameuse condition. Naturellement, vous modifiez donc le code qui concerne chaque nouveau cas. C’est une manière de faire tout à faire naturelle mais pas du tout OCP.
Le problème avec cette manière de faire est simple : si vous devez modifier votre code (un peu partout), il y a des risques pour que vous introduisiez aussi de nouveaux bugs ou dysfonctionnements.
Je vous propose donc de découvrir deux techniques simples pour écrire du code qui peut évoluer sans plus jamais toucher à ce morceau de code.
La première partie concerne la mise en place du dictionnaire. On ajoute des actions en fonction des différents cas.
La deuxième partie concerne la récupération de l’action en fonction du cas. TryGetValue permet de gérer le cas par défaut (la clé n’existe pas dans le dictionnaire).
Comme vous le voyez, cette technique est astucieuse car elle utilise un dictionnaire pour stocker des références vers des actions (méthodes). Elle permet d’ajouter très simplement un nouveau cas sans modifier le bloc if …
Dans cet exemple, le code est très simple. Il faut bien savoir, qu’en général, les blocs if sont plus complexes que ça et c’est donc là qu’il y a vraiment un intérêt à utiliser ce type de mécanisme.
De plus, le dictionnaire pourra aussi être réutilisé pour une autre méthode par exemple. Cela permet donc d’éviter de dupliquer le bloc if.
Faire évoluer le code avec l’héritage
La deuxième technique fonctionne un peu de la même manière. L’idée est de remplacer le bloc if par des classes utilisant l’héritage.
Il y a différentes manières d’utiliser l’héritage pour écrire du code plus évolutif. Je vous propose un exemple qui reprend le même type d’exemple que pour la technique 1.
Ce code permet de calculer le tarif à partir d’un tarif interne et du type de client. C’est simple et efficace. Mais, que pourrions-nous faire si nous devions ajouter d’autres types de clients ? Étendre le switch est une solution, mais il y a aussi la solution d’utiliser l’héritage.
Une autre manière de faire, serait de créer une classe « Client » qui contient une méthode Calculer Tarif. La responsabilité du calcul sera alors transférée à la classe Client.
Comme vous le voyez, cet exemple est plus long. Il demande (un peu) plus de travail. Par contre, vous pouvez très facilement ajouter un type de client sans modifier le code existant. C’est l’avantage de cette technique.
Et peut-être que par la suite, votre classe Client pourra évoluer et proposer des méthodes complémentaires.
Cette technique est simple à mettre en œuvre. Je vous conseille, par contre, de la mettre en place assez tôt dans le développement, sinon elle demandera plus de travail ensuite.
À vous de jouer
Désormais, c’est à vous d’essayer !