Question

Supposons que votre programme fonctionne comme prévu. L’application a un très mauvais code derrière, consomme beaucoup de mémoire, est indéchiffrable et nécessiterait une réécriture majeure pour mettre en oeuvre les changements de fonctionnalités.

À quel moment le refactoring devient-il moins logique qu'une reconstruction totale?

Était-ce utile?

La solution

Joel a écrit un bel essai sur ce sujet:

choses que vous ne devriez jamais faire, première partie

La principale leçon que j’en ai tirée est que, bien que l’ancien code soit horrible et blesse vos yeux et votre sens esthétique, il est fort probable que ce code corrige en grande partie des erreurs et des problèmes non documentés. C'est-à-dire qu'il contient de nombreuses connaissances de domaine et qu'il vous sera difficile, voire impossible, de les reproduire. Vous frapperez constamment contre les bugs de l'omission.

Un livre que j’ai trouvé extrêmement utile est Utiliser efficacement le code hérité de Michael C. plumes. Il propose des stratégies et des méthodes pour aborder le code hérité, même vraiment moche.

Autres conseils

L'un des avantages du refactoring par rapport à la reconstruction est que, SI vous pouvez effectuer le refactoring pas à pas, c'est-à-dire par incréments, vous pouvez tester les incréments dans le contexte de l'ensemble du système, accélérant ainsi le développement et le débogage.

Le code ancien et déployé, même lorsqu'il est laid et lent, présente l'avantage d'avoir été testé minutieusement. Cet avantage est perdu si vous partez de zéro.

Une approche de refactoring incrémental a également contribué à garantir qu’un produit disponible puisse toujours être expédié (et qu’il s’améliore constamment).

Il existe sur le Web un article intéressant sur la comment Netscape 6 a été écrit à partir de rien et il l'a été une mauvaise idée pour les entreprises .

Eh bien, la réponse la plus simple est que s'il faut plus de temps pour refactoriser que pour reconstruire, vous devriez simplement reconstruire.

S'il s'agit d'un projet personnel, vous voudrez peut-être le reconstruire de toute façon, car vous en apprendrez davantage en construisant à partir de zéro que vous ne le feriez avec la refactorisation, ce qui est l'un des grands objectifs des projets personnels.

Cependant, dans un environnement professionnel limité dans le temps, vous devez toujours utiliser à la moindre perte à la société le moins d’argent (pour le même bénéfice) à long terme, ce qui signifie choisir celle qui prend le moins de temps.

Bien sûr, cela peut être un peu plus compliqué que cela. Si d'autres personnes peuvent travailler sur des fonctionnalités pendant le refactoring, cela pourrait être un meilleur choix que de laisser tout le monde attendre qu'une nouvelle version soit construite. Dans ce cas, la reconstruction peut prendre moins de temps que simplement le refactoring aurait pris, mais vous devez prendre en compte l'ensemble du projet et tous les contributeurs du projet.

Lorsque vous passez plus de temps à refactoriser qu'à écrire du code.

Au moment où le logiciel ne fait pas ce qu’il est censé faire. Le refactoring (changer le code sans changer la fonctionnalité) est logique si et seulement si la fonctionnalité est "comme prévu".

Si vous avez le temps de reconstruire complètement l'application, que vous n'avez pas besoin d'améliorer les fonctionnalités de manière incrémentielle et que vous ne souhaitez pas conserver le code existant, la réécriture est certainement une alternative viable. Par contre, vous pouvez utiliser le refactoring pour effectuer une réécriture incrémentielle en remplaçant lentement les fonctions existantes par des fonctions équivalentes, mieux écrites et plus efficaces.

Si l'application est très petite, vous pouvez la réécrire à partir de zéro. Si l'application est volumineuse, ne le faites jamais. Réécrivez-le progressivement, une étape à la fois, en validant que rien n’a été rompu.

L'application est la spécification. Si vous le réécrivez à partir de zéro, vous rencontrerez probablement un grand nombre de bugs insidieux car "personne ne savait que l'appel à cette fonction était censé renvoyer 3 dans ce cas très particulier" (comportement non documenté ...).

C’est toujours plus amusant de réécrire à partir de zéro pour que votre cerveau puisse vous laisser croire que c’est le bon choix. Soyez prudent, ce n'est probablement pas le cas.

J'ai déjà travaillé avec de telles applications. La meilleure approche que j'ai trouvée est progressive: lorsque vous travaillez sur le code, recherchez des opérations effectuées plusieurs fois, regroupez-les dans des fonctions. Gardez un cahier (vous le savez, un vrai, avec du papier, un crayon ou un stylo) pour pouvoir marquer vos progrès. Utilisez-le en combinaison avec votre VCS et non au lieu de cela. Le bloc-notes peut être utilisé pour fournir une vue d'ensemble des nouvelles fonctions que vous avez créées dans le cadre de la refactorisation, et le VCS remplit bien sûr les blancs pour les détails.

Au fil du temps, vous aurez consolidé beaucoup de code dans des emplacements plus appropriés. La duplication de code au cours de cette période sera presque impossible, alors faites-la du mieux que vous pouvez jusqu'à ce que vous ayez atteint le point où vous pouvez vraiment lancer le processus de refactoring, en auditant tout le processus. base de code et y travailler dans son ensemble.

Si vous ne disposez pas de suffisamment de temps pour ce processus (ce qui prendra très longtemps), il est probablement préférable de réécrire à partir de rien en utilisant une approche test-premier.

Oncle Bob pèse dans avec ce qui suit:

  

Quand une refonte est-elle la bonne stratégie?

     

Je suis heureux que vous ayez posé cette question. Voici la réponse. Jamais.

     

Regardez, vous avez créé le désordre, nettoyez-le maintenant.

Une option serait d'écrire des tests unitaires pour couvrir l'application existante, puis de commencer à le refactoriser peu à peu, en utilisant les tests unitaires pour vous assurer que tout fonctionne comme avant.

Dans un monde idéal, vous auriez déjà des tests unitaires pour le programme, mais compte tenu de vos commentaires sur la qualité de l'application, je suppose que vous ne le faites pas ...

Pas de document, pas de rédacteur original, pas de scénario de test et beaucoup de bogues restants.

Je n'ai pas eu beaucoup de chance avec de petits changements incrémentiels lorsque le code dont j'ai hérité est vraiment mauvais. En théorie, la petite approche incrémentielle semble bonne, mais dans la pratique, elle aboutit à une application meilleure, mais toujours mal conçue, que tout le monde pense être désormais VOTRE conception. Quand les choses se cassent, les gens ne pensent plus que c'est à cause du code précédent, cela devient maintenant VOTRE faute. Donc, je ne voudrais pas utiliser le mot refonte, refactor ou toute autre chose qui implique un type de responsable que vous modifiez les choses à votre façon, à moins que je ne le fasse vraiment à ma façon. Sinon, même si vous avez corrigé des dizaines de problèmes, tous les problèmes qui existaient encore (mais n’avaient pas été découverts) vont maintenant être attribués à votre modification. Et soyez assuré que si le code est mauvais, vos correctifs permettront de découvrir beaucoup plus de bugs qui avaient tout simplement été ignorés auparavant, car le code était si mauvais pour commencer.

Si vous savez vraiment comment développer des systèmes logiciels, je refais toute la conception du système. Si vous ne savez PAS VRAIMENT concevoir un BON logiciel, je vous dirai de vous en tenir aux modifications mineures, sinon vous risquez de vous retrouver avec une base de code aussi mauvaise que l'originale.

Une erreur fréquente lors de la refonte est que les utilisateurs ignorent la base de code d'origine. Cependant, la refonte ne doit pas nécessairement signifier ignorer totalement le code ancien. L'ancien code devait encore faire ce que votre nouveau code devait faire, de sorte que, dans de nombreux cas, les étapes dont vous avez besoin se trouvent déjà dans l'ancien code. Copier et coller puis modifier fonctionne à merveille lors de la refonte des systèmes. J'ai constaté que dans de nombreux cas, la refonte et la réécriture d'une application et le vol d'extraits de code d'origine étaient beaucoup plus rapides et beaucoup plus fiables que de petites modifications incrémentielles.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top