Code de qualité, comment bien coder ?
Créer du code de qualité grâce aux principes du clean code. Bien coder et avoir un code propre en respectant les bonnes pratiques.
Créer du code de qualité grâce aux principes du clean code. Bien coder et avoir un code propre en respectant les bonnes pratiques.
La plupart des développeurs n’écrivent pas du code très qualitatif, ce n’est un secret pour personne.
Par manque de formation ou « à cause » d’un budget serré, on se retrouve avec une dette technique incroyable 6 mois après le début du projet.
En tant que développeur, on se doit d’écrire du code de qualité.
C’est pour cela que j’ai décidé de rassembler dans cet article les principales erreurs de développement que je vois en code review.
PS : Ce n’est pas un énième article sur le clean code même si de fait, j’en parle également. C’est surtout un recueil de mon expérience et des mauvaises pratiques que j’ai pu voir en tant que lead developer.
PS2 : Je ne parle pas de SOLID dans cet article car j’en ai fait un billet dédié ici : SOLID – Comprendre les 5 principes en 10 minutes.
Il y a des caractéristiques communes à tout code de qualité.
Le nommage est très important, bien que ce soit un exercice très difficile de trouver le bon nom à donner à une action.
HTTP_KO
=> HTTP_INTERNAL_SERVER_ERROR
)isMOS
=> isMasterOfService
)shouldBeLisible
=> shouldBeReadable
)getAllUsers()
, fetchAllUsers()
, retrieveAllUsers()
)Employee
en front et User
en back par exemple, ça perd tout le monde)Tu peux mesurer la qualité d’un code à sa facilité de compréhension et notamment grâce au nommage..
Le typehint des variables et des fonctions est super important pour la compréhension, la lisibilité générale et l’autocomplétion des IDEs.
Javascript et PHP n’ont pas souhaité typer leur code au début de leur histoire. PHP l’a désormais intégré et Typescript est apparu.
/** @var array */ $users = array();
return 1;
=> return User.NO_MORE_USER
)if
/ else
à rallongeLe typage n’est pas forcément synonyme de qualité du code, néanmoins cela contribue grandement à limiter le risque d’erreur et à rendre le code intelligible.
Tu peux stocker des éléments constants de deux manières différentes.
Response.INTERNAL_SERVER_ERROR
)webservices.name_of_company.users = 'https://...';
)La programmation fonctionnelle a permis de récupérer les sorties avec des chaînes, ce qui est très pratique !
Mais si tu en abuses, les développeurs passant après toi ne comprendront pas ton code.
return data.map((d) => [Object.keys(d)[0], Object.values(d)[0]].map(encodeURIComponent).join('=')).join('&');
for ... of ...
est bien plus rapide que .forEach()
)if ($user = getAllUser()) ...
, car confus et ça peut être mal interprétéFaut-il remonter l’exception ou utiliser un try / catch
?
C’est toujours compliqué à dire suivant les cas d’utilisation. Voici quelques règles pour que tu puisses y voir plus clair.
isUserUnEmployed()
doit remonter true
ou false
)WebServiceNotRespondingException
)InvalidArgumentException
=> UserCannotBeNullException
)Les connaître c’est bien, les utiliser, c’est mieux.
Pour ma part je les connais depuis longtemps, mais je ne les applique réellement que depuis quelques années.
Il m'aura fallu créer beaucoup de code pas terrible pour enfin appliquer ces principes...
Comme toute chose, il faut du temps.
Le principe de responsabilité unique est probablement le plus important.
Il y aurait beaucoup à dire, mais simplement essaye de minimiser les actions de tes fonctions.
Tout ce qui est compliqué n’a jamais produit de bons résultats.
Louis-Napoléon Bonaparte, Les œuvres de Napoléon III (1854-1869)
UserService
=> UserCreatorService
, UserBankingService
)Ça a l’air simple à première vue, mais la limite est parfois obscure…
Imaginons que tu aies deux tableaux. Ces tableaux affichent des informations différentes, mais sont très similaires par leur style et leur template.
Tu pourrais te dire, je vais utiliser une interface pour afficher les objets et gérer les petites différences de style avec des conditions.
À un moment donné, tu te retrouveras avec desif (type === Type.User)
et desif (type === Type.Group)
dans ton code ; pas vrai ?
À partir de combien de chaque il vaudrait mieux faire deux fichiers séparés ?
Globalement tu dois autant que possible :
Moins connu que les autres, mais tellement d’actualité aujourd’hui.
« Tu n’en auras pas besoin ».
À l'heure où les frameworks JS sont utilisés à tout va, on peut supposer que tous les projets n'ont pas besoin de la stack React + Redux + Socket.io + ...
Quel est le besoin de ton client ? Une landing page avec un formulaire tout simple ?
HTML et CSS devraient suffire, PHP si c’est contribuable ou un autre langage back.
L’idée principale c’est de ne pas avoir 20.000 dépendances.
Typiquement on peut prendre l’exemple de jQuery qui n’est je pense plus vraiment utile dans la plupart des cas.
Pourtant je vois tellement de projets encore avec… C’est toujours une des libs JS les plus populaires en 2020.
Et pourtant, on n’en a pas du tout besoin la plupart du temps.
« Faire une seule chose, mais la faire bien ».
C’est toujours mieux que de tout faire et mal ! Contrairement à ce qu’on pense nous les devs, tout bien faire est souvent une chimère.
« Do One Thing And Do It Well. »
La philosophie d’Unix.
Sépare tes fonctionnalités en lot. Dans ces lots crée des parties…
Fais des petites choses, mais fais-les bien.
Cela signifie aussi de créer des fonctionnalités testées et séparées.
Le principe ACID permet de s’assurer qu’une action a bien été réalisée et que son action soit ce que l’on attendait d’elle.
Ce qu’il faut retenir c’est de ne jamais renvoyer OK si on n’est pas certain l’action a bel et bien été réalisée.
route api POST /api/users
, aucune de ces deux requêtes ne doit dépendre de l’autre.Les linters te permettent d’avoir un warning dans ton IDE quand ton code peut être amélioré.
Il permet notamment :
Mieux encore, la plupart des linters viennent avec un fixer, tu peux corriger ces erreurs simplement avec un clic droit…
Les linters rendront ton code bien plus lisible.
eslint
, sass-lint
, php-coder-sniffer
, wpcs
, jslint
…)WordPress
sont différentes de celles de Symfony
)Singleton
, DTO
, Adapter
etc)En théorie le clean code stipule que tu es censé laisser le code plus propre en partant qu’il l’était en arrivant.
Cependant la complexité peut rendre la refactorisation du code difficile, attention aux régressions.
La qualité globale du code du projet est à prendre en compte lorsque l’on est développeur, pas seulement la qualité de SON code.
console.log
» quand tu en vois$variable == $x ? ($x == $y ? array_merge($x, $y, $z) : $x) : $y;
for
a un break
, c’est sûrement un while
C’est toujours un sujet de débat dans la communauté, certains disent que tout doit être commenté, d’autres disent que rien ne doit l’être.
Est-ce que celui-ci doit l’être ?
/**
* Returns a customer based on its id.
*
* @param int $id
* @return Customer
*/
public function getCustomerById(int $id): Customer;
En tout cas un code propre passe par l’utilisation des commentaires.
Essayons de prendre le meilleur des deux mondes et de rester pragmatique.
/** The day of the month. */ primate $dayOfMonth;
TODOs
, ils restent à vie dans le code…Plus une méthode est unique, plus elle est facile à lire, plus elle sera facile à déboguer.
Elle sera même encore plus performante.
UserBasketService
ne s’occupe que des opérations dans le panier, UserPaymentService
s’occupe uniquement paiement sur la plateforme…)UserService
ne veut rien dire, personne sait ce qu’il y a de dedansAvoir un code de qualité passe également par la longueur des différents fichiers.
Ces chiffres sont des indications pour tendre vers un code plus lisible, ils ne sont pas absolus.
Faire du code de qualité est quelque chose de difficile, on a tous notre notion de « code qualitatif ».
Pour écrire un code source de qualité, tu dois écrire du code lisible, propre, compréhensible de tous.
J’aurais voulu parler de l’utilisation des tests dans cet article.
« Mais tester, c’est douter. »
En vérité je n’en ai pas assez mis en place pour pouvoir en parler librement.
Néanmoins les tests sont de très bons outils que tu dois essayer d’utiliser pour rendre ton code encore plus sûr.
D’ailleurs en parlant d’outils, coder sur papier pourrait t’aider à mieux coder !
J’espère que cet article t’aura donné des pistes pour mieux programmer.
Si tu cherches à en savoir davantage sur le clean code, consulte cet article.
Si jamais tu vois des éléments à rajouter à cette liste, n’hésite pas à laisser un commentaire.
Bonjour,
Merci pour cet article fort intéressant.
Peux tu stp expliquer ce point :
=> « Sers-toi des interfaces quand il y en a besoin, cela évite de dupliquer le code et d’avoir des if / else à rallonge »
Et donner un exemple pour celui-là :
=> Si ton for a un break , c’est sûrement un while
Merci d’avance
Hello Maxime,
Avec un peu de retard, je viens de mettre à jour l’article avec deux captures d’écrans !
N’hésite pas si tu as d’autres questions.
Alex
Cet article apporte et renforcer mes connaissances du développement d’applications.
Je reconnais que ce n’est pas facile d’accepter de quitter de foreach vers while.
Vous avez raison de dire « faire du code de qualité est quelque chose de difficile, on a tous notre notion de « code qualitatif » « .
En effet… Bon courage pour ton blog !