mercredi 22 avril 2009

CLEAN CODE, ROBERT C. MARTIN

J'avais énormément appris en lisant le précédant livre d'Uncle Bob, Agile Software Development: Principles, Practices and Patterns. Son catalogue des principes avancés de conception objet et ses métriques de couplage ont été une aide pour développer mieux.

Autant dire que j'attendais le livre suivant Clean Code, traduit en français sous le titre Coder Proprement.

Malheureusement, j'ai été déçu. Le livre est bien, mais j'ai appris bien moins qu'avec le précédant. Aussi, les chapitres rédigés par différents auteurs sont assez irréguliers en qualité. Voici la synthèse de ce qui m'a plu et de ce que j'ai appris.

QUELS SONT LES CRITÈRES DE QUALITÉ D'UN BON CODE?

Voici la définition qu'en donne l'eXtreme Programming:

Par ordre de priorité, le bon code respecte les critères suivants:
  1. Il passe ses tests;
  2. Il ne contient pas de redondance;
  3. Il est explicite;
  4. Il est minimal.
Malheureusement, l'auteur insiste peu sur le fait que les critères 3 et 4 peuvent être contradictoires et que l'ordre des priorités entre ces deux critères est très important. En effet, un code explicite tend à être plus modulaire et à être découpé en petites classes ayant chacune une seule responsabilité et en courtes opérations ayant un seul niveau d'abstraction. Ceci amène à plus de déclarations et donc à plus de code, ce qui s'oppose au critère 4.
D'ailleurs, dans tous les exemples de remaniement du livre, on constate que le code remanié est toujours 2 fois plus volumineux que le code d'origine! Cela ne me choque pas, mais je pense qu'il est important de le souligner clairement.

LIRE ET ÉCRIRE

Nous passons plus de temps à lire du code qu'à en écrire. En rendant le code facile à lire, nous le rendons plus facile à écrire.

LA RÈGLE DU BOY SCOUT

Lorsque nous ouvrons un fichier de code source, nous devons le laisser plus propre que nous l'avons trouvé.

LA LIGNE VIDE

Une opération ne doit pas contenir de ligne vide. Une ligne vide dans une opération sert à aérer son code en regroupant les instructions contribuant à une même action. Une ligne vide est donc un indice indiquant que l'opération passe à autre chose et qu'il y a plusieurs niveaux d'abstraction au sein de la même opération.
Alors, il plus cohérent d'exporter chaque groupe d'instructions contribuant à une même action dans une nouvelle opération nommée selon cette action et à appeler cette nouvelle opération dans l'opération d'origine. Ainsi, il ne reste dans l'opération d'origine que des instructions d'un même niveau d'abstraction.

LIRE LE CODE D'UNE OPÉRATION

Les étapes d'une opération doivent se trouver à un même niveau d'abstraction en dessous du nom de l'opération. Le code d'une opération bien écrite doit pouvoir se lire de la manière suivante:
POUR nom_de_l_opération IL FAUT première_étape_de_l_opération PUIS deuxième_étape_de_l_opération PUIS troisième_étape_de_l_opération PUIS ...
Les différentes étapes de l'opération sont des instructions du langage de programmation ou des appels d'opérations d'un même niveau d'abstraction.

CLASSES ET STRUCTURES DE DONNÉES

Depuis quelques projets, nous remarquons qu'il semble par endroit plus adapté d'écrire un code procédural plutôt qu'un code orienté objet. Est-ce une hérésie? Le constat suivant d'Uncle Bob m'a beaucoup rassuré.

Un code procédural (un code qui utilise des structures de données) facilite l'ajout de nouvelles fonctions sans modifier les structures de données existantes. Un code orienté-objet facilite l'ajout de nouvelles classes sans modifier les fonctions existantes.

Un code procédural complexifie l'ajout de nouvelles structures de données car toutes les fonctions doivent être modifiées.
Un code orienté objet complexifie l'ajout de nouvelles fonctions car toutes les classes de l'arbre d'héritage doivent être modifiées.

Par conséquent, ce qui est difficile pour l'orienté objet est facile pour le procédural, tandis que ce qui est difficile pour le procédural est facile pour l'orienté objet!

Dans un système, nous avons parfois le besoin d'une souplesse d'ajout de nouveaux types de données et choisissons alors une implémentation fondée sur les objets. Si nous voulons disposer d'une souplesse d'ajout de nouveaux comportements, alors nous optons pour les structures de données et les procédures.

Les programmeurs expérimentés savent très bien que l'idée du tout objet est un mythe. Les bons développeurs de logiciels abordent ces questions sans préjugé et retiennent l'approche adaptée à leurs besoins.

DES TESTS PROPRES

Le code de test est aussi important que le code de production. Il doit rester aussi propre que le code de production.
J'avais consacré un billet intitulé Les Tests Sont du Code à ce sujet et c'est d'ailleurs le thème du livre que je suis actuellement en train de lire : xUnit Test Patterns: Refactoring Test Code. Je reviendrai plus longuement sur ce livre car il améliore grandement ma pratique du test automatisé.

L'EVOLUTION DES SYSTEMES LOGICIELS

Les systèmes logiciels sont uniques si on les compare aux systèmes physiques. Leur architecture peut évoluer de manière incrémentale si nous maintenons la séparation adéquate des préoccupations (et le test de leurs constituants!).

SUR LA CONCURRENCE

Incroyable, deux chapitres du livre sont dédiés au développement de logiciels avec traitements concurrents! Malheureusement, il n'y a rien de bien nouveau. Néanmoins, c'est rassurant de lire des recommandations que nous appliquons déjà (voir mon précédant billet Extreme Programming Embarqué). Voici ces constats et recommandations:

La conception d'un système concurrent peut être très différente de celle d'un système monothread. Le découplage du quoi et du quand a généralement un impact très important sur la structure du système.

Gardez le code lié à la concurrence séparé de tout autre code. Ne tentez pas de pourchasser à la fois les bogues du code normal et ceux du code multithread. Assurez-vous que votre code fonctionne en dehors des threads.

CONCLUSION

Malgré quelques déceptions, je ne regrette pas la lecture de ce lire. Néanmoins, je conseillerais plutôt le livre précédant, bien plus enrichissant à mon avis.

Aucun commentaire:

Enregistrer un commentaire