Aller au contenu

Refactoring

·646 mots·4 mins
Sommaire

( Livre bien connu de Martin Fowler)

L’introduction part des principes que

  1. Le code source sera toujours plus souvent lu qu’écrit - Code will be read more often than it will be written.
  2. Que modifier du code existant implique des risques, au travers de l’introduction subtile de nouveaux bugs et de modifications du comportement de certaines fonctionnalités.
  3. En fonction de la base de code existante, une phase de refactoring peut prendre entre plusieurs jours et plusieurs semaines: au plus on creuse, au plus on trouve de choses nécessitant une modification, qui implique à nuoveau de creuser encore, …

The more you dig, the more stuff you turn up… and the more changes you make. Eventually, you dig yourself into a hole you can’t get off. To avoid digging your own grave, refactoring must be done systematically.

Tests (unitaires & intégration)
#

Construire des tests facilite le travail dans la mesure où, quand un bug arrive, les tests qui lui sont associés vont irrémédiablement se planter. Cela indique où la modification doit être apportée.

Tous ces tests doivent être automatiques, de la même manière que la compilation ou la gestion des dépendances. Ne regardez pas la sortie console, faites juste en sorte qu’un worker vous indique ce qui ne fonctionne plus.

  • Les tests unitaires consistent en des tests localisés: quand on reçoit un rapport de bug; on commence par faire un test qui expose le bug (ce qui évitera ensuite les régressions).
  • Les tests fonctionnels utilisent le système comme une black box. Idéalement, ils devraient être écrits par une équipe différente. Pensez aux conditions sous lesquelles le système pourrait planter, et concentrez-vous dessus.

Il y a toujours un risque qu’on rate quelque chose, mais il vaut mieux passer un temps raisonnable à attraper la plupart des bugs, plutôt que de passer des années à leur courir après.

Conseils de programmation
#

  • Trop de paramètres ? Construisez un objet qui les embarque comme champs. Idem quand l’algorithme n’est pas assez clair.
  • Supprimer les paramètres inutiles.
    • Voire ne pas hésiter à refactoriser en ajoutant des paramètres si deux fonctions font la même chose.
    • Voire, remplacer des paramètres par des méthodes explicites (et éviter de décomposer un même objet en plusieurs paramètres).
  • Ne pas hésiter à supprimer des setters ou à modifier la visibilité de certaines méthodes (public -> protected -> private).
  • Au besoin, une factory permet aussi de gérer un constructeur vers des sous-classes (éventuellement en utilisant un brin d’introspection pour aller pêcher la bonne classe par réflexion, sur base d’une chaîne de caractères). Ou alors passer par des méthodes explicites, type Person.newMale() et Person.newFemale().
  • Eviter de retourner des objets qui ne sont pas suffisament typés. On évite ainsi de retourner object() plutôt que MyClass(). Cela évite de downcaster la variable retournée par la fonction appelante.
  • Aucun code d’erreur ! Si c’est nécessaire, implémenter une gestion propre des erreurs (sauf si on finit par avoir tellement de classes qu’un test pourrait suffire…).
  • Dans certains cas, le refactoring fait partie d’une nouvelle fonctionnalité. Ele fait alors partie du processus d’écriture et il est indispensable de se laisser du temps pour implémenter les choses proprement.

By refactoring, you can ensure that you fully understand how the program works and should be designed

L’accumulation de décisions d’architecture à moitié comprises peut éventuellement trucider un programme.

Conclusion
#

Un truc un peu ennuyant quand on lit ce livre, c’est que tous ces exemples “simples”, on a parfois l’impression de lire quelques contradictions.

Par exemple, avec la délégation simple: si une classe fait trop de délégations simples et agit comme un middle-man, il faut alors la dégager, parce qu’elle génère un trop grand couplage de classes. Du coup, il ne s’agit pas vraiment d’un livre de recettes à suivre, mais plus d’une concrétisation de l’intuition par l’expérience.

Plus précisément, il s’agit d’une clarification étape par étape de choses que l’expérience nous fait faire intuitivement.