Blog // Exirel.me

Ugly code

Par Florian Strzelecki - 01:56 - 28.09.2011

Tags : Framework, Programmation, Bonne pratique, Chaton, Optimisation, Problème, loldev, Technique

Il est parfois difficile de dire d'un code qu'il est bon ou mauvais, qu'il est moche ou élégant. Parfois, les deux se confondent dans un doute profond sur la nature d'une idée, et sur son implémentation.

Beautiful is better than ugly.

Heureusement, parfois, il y a du code php/java/python/javascript/ruby/perl/autre bien sale et c'est très facile à repérer.

Notez l'effort pour ne pas troller toujours sur le même langage.

Code Size

Je lisais très récemment cet article assez ancien (décembre 2007) Code's worst ennemy, qui relate un problème encore très d'actualité, qui est la taille du code - et surtout le fait que c'était encore et toujours considéré comme un "non-problème", ce qui est dérangeant en soi.

Ayant depuis quelques mois comme leitmotiv Moins de code, plus de fonctionnalité, je ne pouvais qu'être d'accord sur cette idée.

D'ailleurs, j'ai trouvé intéressant que l'un des commentaires de l'article de 2007 soit le suivant :

How about turning parts of the program as libraries and publishing them with some Open Source license?

Ce qui se rapproche de ma conclusion qui est qu'il vaut mieux écrire le moins de code possible dans le cadre qui nous est donné, à savoir le framework (s'il y en a) et le langage (avec ses librairies natives). Et, toujours, si possible, factoriser le code pour le compartimenter en librairies, qui peuvent, si elles sont bien séparées et indépendantes, être beaucoup plus simple à maintenir (notamment avec des tests unitaires).

Bref, la taille du code, ça compte beaucoup.

Code Complexity

Un mauvais code est un code trop complexe, et cette complexité peut avoir bien des origines - et je le pense, la taille du code en fait partie, mais elle n'est pas la seule responsable.

La duplication du code est un facteur de complexité, notamment pour la maintenance. Plus le code est dupliqué, plus un bug à résoudre va demander de temps et d'énergie : isoler la vraie partie du code qui pose problème n'est que la première étape, car il faut ensuite reporter cette modification partout.

L'usage de la magie du langage est un autre facteur de complexité. Je le vois particulièrement avec PHP, où il est possible de définir les méthodes __get, __set, et __call, qui peuvent devenir de vrai casse-tête à comprendre.

Dans la magie, je range aussi ce genre de comportement, assez fréquent en PHP pour certaines choses :

$className = 'MaClasse';
$object = new $className();

Oui, cela est parfois nécessaire, et souvent "utile", mais cela a un coût : la lisibilité du code. Sans une excellente documentation, cela peut très vite devenir un calvaire - d'autant que nos IDEs modernes sont incapables de nous aider là dessus.

[sur]couche de Code

Autre point de complexité : les couches et les couches de classes et d'objets. C'est d'autant plus remarquable avec les interfaces et les classes (PHP et Java), et encore plus avec tout ce qui touche aux exceptions.

Qui n'a jamais vu ce genre de code ?

try {
    // throw exception (like ExternalLibException)
} catch (Exception $e) {
    throw new MyAppException($e->getMessage(), $e->getCode(), $e);
}

Ce qui peut être bien... mais imaginez ensuite vous retrouver avec cet enchaînement là :

ExternalLibException -> MyAppVerySpecificException -> MyAppException -> MyAppProxyException -> MyAppBaseException -> ...

Et le tout, avec des exceptions qui étendent une classe d'exception, qui étend une classe d'exception, qui étend... vous m'avez compris !

La programmation objet a ceci de terrible qu'elle est diablement facile à mettre en place, mais diablement facile à pervertir. Trop d'objet tue l'objet - et certains langages n'aident pas du tout d'ailleurs.

Il ne sera pas fait mention ici du fait que certains langages mélangent beaucoup trop objet et type de base, comme... ah ben non, n'en faisons pas mention.

La dette technique

Autre ennemis du code claire et limpide, de l'application stable et performante, c'est la dette technique. Ou plutôt, l'absence de prise en compte de cette dette technique.

Car, qu'on la prenne en compte ou pas, la dette technique se paye. Toujours. Et pas forcément quand on le voudrait, ni comme on le voudrait.

Parce que parfois, il est juste trop tard pour faire mieux ; il fallait se réveiller plus tôt.

Un peu comme la dette des pays de l'Union Européenne, à tout hasard.

Code Solution

Quoi qu'il en soit, avec tous ces problèmes, je ne suis toujours pas en mesure de vous dire exactement pourquoi un code est mauvais, ni comment s'en rendre compte : cela se fait au cas par cas. Mais pour vous aider, il existe des indicateurs, qu'il faut non seulement savoir obtenir, mais aussi, savoir interpréter.

Les indicateurs à suivre étant pour moi les suivants (à peu près dans l'ordre) :

Plus il y a de code, plus il y a de risques d'erreurs - c'est humain, et c'est normal. Et puis plus il y a de code, plus il y a un risque de dupliquer du code. Et le code dupliqué, c'est une dette technique à résorber un jour ou l'autre.

Il y en a d'autres, qui concernent plutôt l'application dans son ensemble (là aussi à peu près dans l'ordre d'importance pour moi) :

Et puis, je dirais, là comme ça, il y a quelques principes à respecter :

Il y a tant de choses que j'aimerais dire sur le code et la qualité. Mais je vais laisser ça pour plus tard, et pour d'autres personnes.

Après tout, la seule chose à retenir de tout ça :

À chaque fois qu'un développeur écrit du code sale, Dieu tue un chaton.