Refactorisation à faible impact et nettoyage du code du code bâclé en attendant les exigences


17

J'ai hérité d'une base de code existante pour un produit qui est manifestement bâclé. La conception fondamentale est terriblement inadéquate, ce que je ne peux malheureusement pas faire sans un refactor complet (couplage HAUT, faible cohésion, duplication rampante de code, pas de documentation de conception technique, tests d'intégration au lieu de tests unitaires). Le produit a une histoire, une forte exposition aux clients critiques de "vache à lait" avec une tolérance minimale au risque, une dette technique qui fera rougir les Grecs, une base de code et une complexité TRÈS importantes et une approche défaitiste fatiguée par les bogues de l'équipe avant. moi.

L'ancienne équipe a quitté le navire pour une autre division afin qu'ils aient la possibilité de ruiner un autre projet. Il est très rare que j'éprouve un échec de projet d'incompétence technique par opposition à un échec de gestion de projet, mais c'est effectivement l'un de ces cas.

Pour le moment, je suis seul mais j'ai beaucoup de temps, une liberté de décision et une orientation future et la capacité de construire une équipe à partir de zéro pour m'aider.

Ma question est de recueillir des avis sur le refactoring à faible impact sur un projet comme celui-ci lorsque vous avez du temps libre pendant la phase de collecte des exigences fonctionnelles. Il existe des milliers d'avertissements du compilateur, presque tous des importations inutilisées, des variables locales non lues, l'absence de vérification de type et des conversions non sécurisées. Le formatage du code est si illisible et bâclé qu'il semble que le codeur souffre de la maladie de Parkinson et ne puisse pas contrôler le nombre de fois où la barre d'espace a été enfoncée sur une ligne donnée. D'autres ressources de base de données et de fichiers sont généralement ouvertes et jamais fermées en toute sécurité. Arguments de méthode inutiles, méthodes en double qui font la même chose, etc.

Pendant que j'attends les exigences pour la prochaine fonctionnalité, j'ai nettoyé des choses à faible impact et à faible risque au fur et à mesure et je me suis demandé si je perdais mon temps ou si je fais la bonne chose. Et si la nouvelle fonctionnalité signifie extraire du code sur lequel j'ai passé du temps plus tôt? Je vais commencer une approche Agile et je comprends que c'est acceptable et normal de constamment refactoriser pendant le développement Agile.

Pouvez-vous penser à des impacts positifs ou négatifs de mon action que vous aimeriez ajouter?


1
Récupérer ce qui vaut la peine d'être récupéré, réécrire le reste ...
SF.

"Il est très rare que j'expérimente un échec d'un projet d'incompétence technique par opposition à un échec de gestion de projet [...]" Comme c'est vrai, +1.
Gregory Higley

Réponses:


22

Je voudrais tout d'abord souligner que les tests unitaires ne remplacent pas les tests d'intégration. Les deux doivent exister côte à côte. Soyez reconnaissant que vous ayez des tests d'intégration, sinon l'un de vos petits refactorings pourrait bien faire balancer une des vaches à lait à faible tolérance.

Je commencerais à travailler sur les avertissements du compilateur et les variables et importations inutilisées. Obtenez d'abord une construction propre. Commencez ensuite à écrire des tests unitaires pour documenter le comportement actuel, puis lancez le véritable refactoring.

Je ne vois vraiment aucun impact négatif. Vous gagnerez beaucoup de compréhension approfondie de la base de code, ce qui vous aidera à effectuer des refactorisations plus importantes. Il est presque toujours préférable de refactoriser que de réécrire, car pendant la refactorisation, vous avez toujours un produit qui fonctionne, tandis que pendant la réécriture, vous n'en avez pas. Et à la fin, les ventes du produit doivent payer votre salaire.

Une fois que les exigences commencent à arriver, j'utiliserais ce que j'appelle l'approche Spotlight. Faites la chose agile habituelle (priorisez, puis coupez une petite dalle pour une itération, et travaillez-y) et laissez un peu de temps pour les améliorations de code. Refactorisez ensuite où vous travaillez de toute façon. Au fil du temps, cela couvrira de vastes zones de la base de code sans que vous ayez à vous aventurer dans des domaines où vous auriez des difficultés à justifier auprès de la direction pourquoi vous travaillez sur cette partie du code.


J'aime vraiment cette réponse. J'ai besoin d'une compréhension plus approfondie de la base de code et les vaches à lait DOIVENT payer mon salaire et nous permettent également de travailler sur de meilleurs nouveaux projets pour d'autres clients où j'ai la possibilité de recommencer à zéro et de le faire dès le début.
maple_shaft

10

Écrire des tests unitaires pourrait être une utilisation plus utile de votre temps: cela vous donnera un aperçu du fonctionnement actuel de la base de code, et si vous décidez de partir de ce que vous avez plutôt que de tout réécrire à partir de zéro, vous aurez une base solide faire des changements sans prendre trop de risques. Il est probable qu'en écrivant des tests unitaires, vous apporterez également des modifications à la base de code juste pour lui donner une forme testable; ceux-ci sont bons, car testables en unité signifie généralement aussi modulaire, encapsulé et principalement indépendant de l'état externe. Et, surtout, des tests unitaires bien écrits sont une documentation technique inestimable. Avec les tests unitaires en place, vous serez en mesure de juger ce que la base de code actuelle peut et ne peut pas faire, plutôt que de faire des suppositions ou de réécrire des choses au cas où.


2
Commencez par les plus faciles et montez?
tdammers

2
C'est toujours le problème dans mon expérience - un code comme celui-ci n'est jamais écrit pour permettre les tests et vous finirez par devoir faire d'énormes refactorings sinon une réécriture pure et simple pour même permettre des tests unitaires en premier lieu.
Wayne Molina

2
Si le code n'a pas été conçu pour les tests, c'est une raison de plus pour le contourner - mais en toute sécurité. Lire le livre de Michael Feathers "Travailler efficacement avec le code hérité"; il a des recettes pour rendre le code non testable testable.
Joe White

1
Je suis d'accord; en précisant simplement, d'après mon expérience, qu'il n'y a pas de tests, il faudrait initier un énorme refactoring pour le préparer en premier lieu aux tests, ce qui entraîne plus de temps de refactoring «perdu», ce qui rend plus difficile l'écriture des tests, ce qui il est alors beaucoup plus difficile de refactoriser quoi que ce soit.
Wayne Molina

1
Il faut de l'expérience et un bon jugement. Tout ne peut pas (ou ne devrait pas) être rendu testable à l'unité.
tdammers

1

Mélanger les réponses - ma pensée serait de mélanger les tests et le nettoyage - peut-être 50/50? Si vous travaillez dans une zone faisant une approche TDD - configurez les tests dont vous avez besoin pour savoir que les tests unitaires et d'intégration sont comme vous le souhaitez, puis commencez à corriger. Continuez comme le temps vous le permet.

Cela signifie probablement que vous ne progresserez pas autant, mais cela signifie que vous aurez une base de code bien stable dans certains domaines, au moins, et vous aurez une bonne base de départ.

Au départ, ma réaction intestinale a été "cela peut-il vraiment faire mal de nettoyer un code cassé?" (aka, erreurs du compilateur), mais je me suis souvenu des fois où la résolution du problème a en fait cassé la fonctionnalité dans certains cas vraiment étranges, car au lieu d'un thread mourant, il a laissé de la mémoire dans de mauvais endroits - essentiellement une mauvaise interruption masquait une erreur encore pire. Cela peut littéralement être une boîte de Pandore de surprises désagréables.

Étant donné que vous faites cela en attendant plus d'exigences, je pense que tout ce que vous pouvez pour diagnostiquer le chaos ajoutera grandement à votre santé mentale à long terme.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.