Refactorisation

Un article de Wikipédia, l'encyclopédie libre.

La refactorisation (anglicisme venant de refactoring) est une opération de maintenance du code informatique. Elle consiste à retravailler le code source non pas pour ajouter une fonctionnalité supplémentaire au logiciel mais pour améliorer sa lisibilité, simplifier sa maintenance, ou changer sa généricité (on parle aussi de remaniement). Une traduction plus appropriée serait réusinage. C'est donc une technique qui s'approche de l'optimisation du code, même si les objectifs sont radicalement différents.

Sommaire

[modifier] Pourquoi refactoriser ?

Au fur et à mesure de la vie d'un logiciel on est amené à implémenter de nouvelles fonctions ou à corriger des bugs. Or ces modifications ne s'imbriquent pas toujours avec élégance dans l'architecture du logiciel.

Le code source d'un programme tend donc à devenir de plus en plus complexe au fur et à mesure de son existence.

Cela est notamment vrai avec les techniques modernes de développement itératif incrémental où le logiciel entre en phase de modification pratiquement dès le début de son existence.

Il est donc important de mettre en œuvre des techniques qui permettront de toujours conserver un code aussi simple que possible. Cela consiste à :

  • S'assurer que toute l'information nécessaire est disponible
  • Supprimer toute information redondante ou duplication de code
  • Simplifier l'algorithmique des méthodes
  • Limiter la complexité des classes
  • Limiter le nombre de classes

[modifier] Les niveaux de refactorisation

On peut distinguer plusieurs niveaux de refactorisation, selon l'impact des modifications sur le déroulement du programme et les risques rencontrés. En pratique, durant une même session de refactorisation on jonglera souvent entre ces divers niveaux.

[modifier] Modification de la présentation

À ce niveau on cherche à simplement améliorer la présentation du code source sans modifier le code exécuté. Ce type d'amélioration concerne donc essentiellement les commentaires (suppression des commentaires superflus, ou ajout de commentaires sur des sections complexes) et la mise en page (indentation du code, passages à la ligne).

[modifier] Modification de l'algorithmique

Ce type de modification est destiné à conserver des méthodes aussi simples que possible. Cela est le plus souvent réalisé en scindant une méthode ou un algorithme en plusieurs parties ou en confiant à un objet annexe une partie du traitement.

Dans ce type de modification, il est tout à fait possible (et fréquent) d'introduire des bugs, il est donc fortement conseillé de construire une batterie de tests unitaires et de l'exécuter après chaque modification.

[modifier] Relocalisation de procédures

C'est un cas particulier de la modification de l'algorithmique. Cela consiste à déplacer une procédure dans une autre procédure ou dans le corps principal de la classe. (à compléter).

[modifier] Refonte du design

C'est le type de modification le plus radical puisqu'il consiste à modifier la hiérarchie de classes composant l'application. Il est là aussi préférable de procéder par petites modifications et d'exécuter une suite de tests à chaque fois. Il est par ailleurs très difficile de réaliser une refonte en profondeur sans outil spécialisé comme un explorateur de classes.

[modifier] Des activités de refactorisation

[modifier] Suppression du code mort

Le code mort est du code qui ne sert à rien car il n'est jamais appelé par une autre partie du programme. Il ne sert donc qu'à rendre le code source plus complexe et à provoquer des risques de confusion.

Le plus difficile est bien entendu de détecter le code mort, on peut pour cela utiliser plusieurs techniques:

  • recherche statique par l'outil grep sur le code source pour vérifier qu'une méthode est bien appelée quelque part
  • analyseur de références croisées (par exemple l'outil objxref livré avec le compilateur turbo C de Borland)
  • outil de mesure de couverture de code. C'est sans doute la méthode la plus pratique puisqu'elle permet également de vérifier des portions de méthodes. Elle est également la plus risquée puisque du code peut être marqué comme non couvert simplement parce que la suite de test n'est pas complète (ce qui est en pratique toujours le cas).

Il existe une autre forme de code mort: le code commenté. Il arrive souvent que suite à des modifications, on laisse des pans entiers de l'ancien code pour pouvoir éventuellement revenir à la version antérieure facilement. Ce type de code devrait également être supprimé à la fin de la session de développement.

Dans tous les cas, il n'est jamais recommandé de conserver du code qui pourrait servir un jour. Il est toujours préférable de le supprimer de la version de travail et d'utiliser un outil de gestion de versions pour archiver ce type de code.

[modifier] Ajout d'assertions

Les assertions sont une technique de programmation qui consiste à vérifier qu'un certain nombre de conditions sont vérifiées. Elles sont très intéressantes d'une part car elles permettent de simplifier le déboggage en détectant les erreurs au plus tôt, mais également parce qu'elles sont placées à l'intérieur du code qu'elles contrôlent et peuvent donc aider à la compréhension de l'état du système.

[modifier] Renommage

Au fur et à mesure du développement d'un logiciel, le rôle des classes et des méthodes devient plus clair. Il est donc souvent utile de modifier les noms de classes ou de méthodes pour bien indiquer ce rôle.

[modifier] Commentaires

Les commentaires sont un sujet assez controversé de documentation du logiciel. Il est de toute façon important de toujours garder les commentaires synchronisés avec le code.

[modifier] Références

  • Jean-Philippe Retaillé, Refactoring des applications Java/J2EE, Eyrolles, 2005, 390 p., ISBN 2212115776
  • Martin Fowler, Kent Beck, Refactoring: Improving the Design of Existing Code, Addison-Wesley Professional, 1999, 464 p., ISBN 0201485672
  • Joshua Kerievsky, Refactoring to Patterns, Addison-Wesley Professional, 2004, 400 p., ISBN 0321213351