Le principe SOLID

Le principe de la responsabilité unique, la première lettre du fameux principe SOLID. Bien que SOLID soit généralement lié à la programmation orientée objet, je considère la responsabilité unique comme un élément essentiel dans n’importe quel type de développement. Voyons voir plus en détail ce qu’il en est !

Que faut-il comprendre à travers “la responsabilité unique” ?

Pour faire au plus simple, il faut que votre ensemble de codes ne sache faire qu’une seule chose. A la base, on parle de ce principe pour une class en programmation orientée objet ( POO ) ; c’est à dire qu’une class ne doit s’occuper que d’une seule partie du code, ce dont pourquoi elle existe. Vous êtes toujours perdu ? Pas de panique, regardons ensemble la class suivante.

Le code est en français – et qu’importe si pour faire du café ce n’est pas tout à fait comme ça. On est là pour comprendre la philosophie.

Dans cet exemple, on retrouve une class dite “MachineACafe”. On s’attend donc à ce que celle-ci nous permette de faire du café ? Pourtant, en observant les différentes méthodes à notre disposition, cette machine à faire du café… fait aussi du thé et de la bière. Pourtant, ce n’est pas ce qu’on lui demande de faire ? Cette class ne respecte donc pas le principe de la responsabilité unique qui est, pour elle, de faire du café.

Pour aller plus loin, il faudrait donc atomiser le code en différentes class.

Nous voilà avec des class qui respectent la single responsibility. Alors évidemment, cela fait plus de fichiers… mais c’est bien plus lisible ! Par exemple, lorsque vous utilisez un éditeur de texte ou n’importe quel IDE, vous pouvez faire des recherches rapides sur le nom des fichiers. Vous avez un problème avec votre machine à faire de la bière ? Il suffit de chercher le nom de fichier “machine biere” et vous serez au bon endroit. Cela demande la rigueur de nommer votre fichier de la même manière que votre class mais cela fait aussi partie des normes PSR en PHP.

Si nous avions eu plusieurs méthodes dans notre seul fichier et que nous aurions du chercher la fonction “faireDuThe”, cela nous aurait obligé de faire une recherche globale sur le projet en tentant de trouver le nom de notre méthode. Sachant que le nom de celle-ci n’a aucun rapport avec le fichier, personne n’aurait eu l’idée d’aller chercher dans cette class. C’est le moment pour vous de prendre une tarte pour manquement aux bonnes pratiques !

Clairement, lors d’une code review, la class que l’on avait au début ne passera pas. Généralement, si l’on ne respecte pas la responsabilité unique on se retrouve rapidement avec ce que l’on appelle des “GodObject”. Un objet “Dieu” qui sait tout faire. Vous vous retrouvez ensuite six mois plus tard à ne plus comprendre tout ce qui se passe dans votre fichier qui fait déjà quelques centaines de lignes ( allez.. 1000 )

La responsabilité unique d’une fonction.

Comme je vous l’expliquais au tout début de l’article, je considère que ce principe est applicable également à l’écriture d’une fonction quelconque. Prenons l’exemple d’une fonction qui va devoir s’occuper d’envoyer un email suite à une inscription d’un utilisateur et qui ne respecte pas la single responsability. Pensez à bien lire les commentaires car les instructions en PHP n’ont aucun intérêt.

On va s’arrêter ici car c’est une catastrophe… Pourquoi ? Cette fonction qui enregistre un utilisateur fait trop de choses :

  • Elle “nettoie” les paramètres que l’on va recevoir du formulaire d’inscription
  • Elle enregistre en base de données l’utilisateur
  • Elle s’occupe du template de l’email
  • Puis… elle envoie un email à l’utilisateur à la fin de l’inscription

On est d’accord, l’enregistrement d’un utilisateur est la combinaison de ses différentes actions. Mais, ce n’est pas le rôle d’une seule fonction. En ayant définit les différentes actions à effectuer, ce sont donc différentes fonctions qui doivent exister ! Voyez plutôt :

Sans commentaire sur l’utilité de ce code et sur le fait qu’on pourrait faire bien mieux. Mais l’idée est de vous montrer la responsabilité unique de chacune de ces fonctions.

D’un côté, la fonction registerUser va permettre l’assemblage de ces fonctions. De l’autre côté, chacune des fonctions s’occupe d’un seul traitement, ce pour quoi elle a été créée. L’enregistrement en base de données, la gestion du template d’email, la gestion du sujet de l’email, etc …

Convaincu ? Je l’espère ! Soyez responsable alors, vous êtes rarement seul à lire du code.