[DUMD 4/24] Restez simple

Auteur du billet de blog : Nicolas Hilaire - Neotech Solutions

Nicolas Hilaire

Consultant .NET
  Publié le mercredi 26 octobre 2016

Artisan logiciel particulièrement intéressé par les technologies .NET. Polyvalent et curieux, je suis néanmoins à l'écoute des autres technologies du marché. MVP (Microsoft Most Valuable Professional) de 2007 à 2014, je suis également auteur d'un ouvrage pour apprendre le C#, à destination des débutants et de plusieurs MOOCs sur le C#, Windows Phone ou ASP.NET MVC...

Quatrième billet sur comment devenir un meilleur développeur. Pour retrouver le sommaire ainsi que tous les liens, rendez-vous sur le premier billet.

 

J'essaie autant que possible d'être un développeur pragmatique. J'écris du code pour résoudre un problème et j'essaie de me concentrer uniquement sur ce problème sans tenter d'anticiper les autres. Premièrement parce que tout bon développeur est un développeur paresseux (paresseux, mais pas fainéant !) et ensuite parce qu'on ne sait jamais si anticiper ne sera pas une perte de temps.

Dans ce chapitre, nous allons explorer les concepts liés à trois acronymes que vous devez garder en tête lors de vos développements. Certains développeurs sont très bons en marketing et ces acronymes simples sont autant d'atout utiles pour se rappeler des bonnes pratiques.

 

DRY : Don't repeat yourself

Le principe DRY consiste à faire en sorte de ne jamais refaire deux fois la même chose. En tous cas, d'essayer au maximum.

Le but est de factoriser le code qui est identique. Oui - je sais - comme vous, ça m’est déjà arrivé de faire un copier-coller plutôt qu’un refactoring adéquat. Honte à moi. o_O

Le but de DRY est d'éviter la redondance de code pour en faciliter la maintenance et les évolutions. Imaginons que nous fassions un calcul complexe à un endroit du code, disons un calcul de montant de panier dans un site d'e-commerce. Et puis plus tard, dans une autre partie de l'application, disons dans la partie d'administration des commandes, on ait besoin à nouveau de calculer le montant d'un panier afin de vérifier qu'il n'y a pas d'erreur dans la commande. Il pourrait être tentant de copier-coller la partie du code qui fait le calcul du panier et de la réutiliser dans notre partie d'administration ...

Sauf que voilà, vous vous retrouvez avec un code dupliqué, potentiellement à deux endroits ou plus. Et si plus tard nous avons besoin d'ajouter du code dans ce calcul pour prendre en compte des éventuelles promotions ou pourquoi pas la réduction associée à l'utilisation d'un bon d'achat, alors il faudra modifier ce code ainsi que celui qui est présent dans la partie d'administration. Du travail en plus et un risque d'erreur augmenté.

Et plus tard, si on découvre un bug dans l'algorithme ? Il faudra le corriger aux deux endroits. Et que ce passe-t'il si on oublie de corriger l'autre endroit parce qu'on a confié ce travail au nouveau stagiaire qui ne connaît pas la partie d'administration ? Ou si simplement parce que nous l'avons oublié nous même ...

Pour limiter ces risques, DRY nous recommande de ne pas dupliquer de code et plutôt de partager le même code à ces deux endroits différents.

Voici un exemple naïf de code dupliqué :

 

 

Et maintenant une version respectant un peu plus le principe DRY :

 

 

Il suffit d'introduire une méthode qui s'occupe de faire le calcul du produit et de la réutiliser à tous les endroits où on en a besoin. Bien sûr, en orienté objet, nous aurions créé cette méthode directement dans la classe Panier, pour avoir :

 

 

mais ne voulant pas la faire apparaître ici pour des questions de lisibilité, je suis passé par une méthode qui factorise ce calcul.

Utilisez et réutilisez votre code à différents endroits et n'hésitez pas à remanier votre code comme nous l'avons fait juste au-dessus pour permettre cette réutilisation.

 

KISS : Keep It Simple Stupid

Le second acronyme que nous allons voir n'est pas là pour que vous me fassiez des bisous, mais pour vous rappeler de faire des choses simples. Il y a plusieurs variations à KISS que vous pourrez retrouver dans wikipedia, mais l'idée derrière est de faire en sorte de ne pas sur-complexifier une solution et de faire en sorte de répondre le plus simplement possible à un problème. Plus c'est simple et plus cela sera facile à maintenir ou à déboguer.

L'adage populaire "pourquoi faire compliqué quand on peut faire simple" est tout à fait représentatif du principe KISS.

Il n'y a pas grand chose de plus à rajouter sur ce principe, si ce n'est qu'il doit vous rester à l'esprit lorsque vous développez. Nous autres développeurs aimons (parfois) faire de la technique pour la technique et utiliser des trucs complexes juste pour se faire plaisir. C'est vrai que c'est sympa, mais il faut raisonner en termes d'efficacité. Plus c'est simple et plus vous aurez de facilité à le créer et surtout à le maintenir.

Pour réaliser ce stockage de données, a-t'on vraiment besoin de cette base de données No-SQL dans le cloud accessible par une authentification via un proxy encrypté synchronisé avec l'âge du capitaine ? Peut-être que dans un premier temps, on pourrait simplement enregistrer ça dans un fichier en local... Et puis enrichir les choses quand on en aura vraiment besoin ; ce qui m'amène au principe suivant :

 

YAGNI : You Ain't Gonna Need It

YAGNI peut-être traduit par : vous n'en aurez pas besoin. Ce principe est là pour nous rappeler que nous avons tendance à anticiper des besoins avant même que ceux-ci ne soient vraiment utiles ; sachant que la plupart du temps, ils ne le sont pas.

Donc, grosso modo, tant qu'une fonctionnalité n'est pas absolument nécessaire, ne la développez pas.

Cela vous occasionne de la charge de travail supplémentaire, complexifie votre code, risque d'introduire des nouveaux bugs, alors que si ça se trouve, on ne s'en servira jamais !

Nous avons souvent tendance à vouloir développer des choses "génériques" car nous imaginons que sans doute quelqu'un pourra le réutiliser plus tard. Et c'est bien souvent un fantasme des managers, de se dire qu'une équipe va faire tel développement un peu plus générique, comme ça, l'autre équipe n'aura rien à faire, juste à réutiliser le code. Et hop, du temps et de l'argent gagné !

Mon expérience me fait dire que le besoin que nous avons à un instant T n'est que très rarement le besoin de quelqu'un d'autre. Nous allons passer du temps à faire quelque chose de "générique" qui au final ne correspondra pas au besoin des autres. Fatalement ils auront des besoins légèrement différents et vont s’embêter à faire rentrer leur carré dans notre rond. Et même en tapant fort, ça rentrera mal !

De la même façon, nous avons tendance à utiliser des frameworks ou des fonctionnalités en se disant qu'on en aura besoin plus tard. Une architecture particulièrement découpée, des frameworks complexes, du MVC, ou une base de données particulière, alors que pour l'instant, nous n'avons besoin peut-être besoin que de stocker des fichiers. Alors oui, sans doute que nous allons avoir besoin d'une base de données plus tard, mais plus on retarde la décision du choix d'une base de données et plus on aura d'informations pour faire le bon choix. Peut-être qu'utiliser des fichiers sera suffisant, peut-être qu'une base de données No-SQL orientée colonnes sera plus adaptée, etc.

 

Conclusion

Ces principes sont des éléments de bon sens. Ne pas refaire deux fois la même chose, ne pas faire des choses inutiles ou faire des choses simples. Pourtant, on observe bien souvent que ces comportement ne sont pas respectés dans les applications sur lesquelles nous intervenons. Parfois, il peut y avoir une bonne raison à la duplication, mais il faut que ça soit clairement justifié et parfaitement documenté. Il existe des stratégies pour ne dupliquer que des parties de code, nous en parlerons dans la partie sur les designs patterns avec le patron de méthode.

N'oubliez pas de garder les choses simples et de résister à la tentation (fantasme ?) de la réutilisabilité. Cela fonctionne rarement et on perd plus de temps à tenter de rendre les choses génériques qui au final ne fonctionneront pas forcément pour les autres cas d'usages.

Quand vous serez en train de déboguer votre application, rappelez-vous : plus c'est simple et plus c'est maintenable (et facile à déboguer).

 

Prochain billet : Utilisez correctement l'orienté-objet.

Commentaires