Comment puis-je mettre à jour une grande base de code héritée pour répondre à des normes de qualité spécifiques?


10

Il y a beaucoup d'informations sur les outils et les techniques pour améliorer les bases de code héritées, mais je n'ai rencontré aucune étude de cas réussie dans le monde réel. La plupart des conseils sont au niveau micro, et bien qu'utile, ne convainc pas beaucoup de gens en raison d'un manque de preuves, cela peut aider au niveau macro.

Je recherche spécifiquement des améliorations incrémentielles qui se sont avérées être un succès dans le monde réel lors de la mise à jour d'une grande base de code héritée pour répondre aux normes de qualité d'aujourd'hui, et non une réécriture complète.

Avant:

  • Grand: supérieur à 1 MLOC
  • Héritage: pas de tests automatisés
  • Mauvaise qualité: complexité élevée, couplage élevé, défauts d'échappement élevés

Après

  • Tests automatisés
  • Mises à jour / maintenance plus faciles
  • Haute qualité: complexité réduite, code découplé, quelques défauts échappés

Quel type d'étapes incrémentielles a été prouvé dans le monde réel pour mettre à jour une grande base de code héritée avec succès pour répondre aux normes de qualité ci-dessus, sans passer par une réécriture totale?

Si possible, incluez un exemple d'entreprise ou d'étude de cas d'un grand projet hérité qui a subi un processus d'amélioration de la qualité «réussi» dans votre réponse pour le sauvegarder.




7
Toute l'industrie financière? Une grande partie fonctionne sur du code FORTRAN vieux de 40 ans. Contrairement à Netscape, ils ne peuvent pas le jeter et le réécrire à partir de zéro, donc il s'est progressivement amélioré tout ce temps.
MattDavey

2
dans mon PDV, Netscape peut difficilement être utilisé comme un exemple réussi - le projet a mis fin à l'entreprise ... qui était à l'époque une organisation commerciale à but lucratif. Je ne peux pas imaginer que les actionnaires ouvrent l'étagère du haut ce jour-là ... En fait, il y a un livre blanc bien connu sur le thème "Que ne pas faire" utilisant Netscape comme étude de cas parfaite ...
mattnz

2
Bonjour @mikelong J'ai édité votre question pour essayer de la rouvrir. Votre question initiale demandant une liste d'exemples, qui est considérée comme "non constructive" par les normes StackExchange. N'hésitez pas à le modifier davantage pour ajouter plus de détails sur ce que vous entendez par "haute qualité", ou pour mettre à jour le libellé si j'ai fait une erreur. :)
Rachel

Réponses:


8

Des livres comme http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052 devraient être suffisamment témoins de la taille et de l'héritage des bases de code de mauvaise qualité héritées de l'industrie.

Je suppose que vous n'avez pas entendu ou vu et, plus important encore, que vous n'en entendrez probablement parler que lorsque vous travaillerez sur l'un d'eux vous-même, personne ne semble capable pour diverses raisons de sortir net et de dire que son code base était tout ce qui précède sans faire face à des répercussions non triviales.

Cela pourrait expliquer le manque d'études dont vous parlez. Si vous lisez suffisamment de livres, par exemple, Deep C Secrets de Peter van der Linden, vous lirez environ des millions de bugs où la partie sur laquelle le projet les avait manquera.

REMARQUE: je voulais en faire un commentaire, mais c'était trop long. Je comprends que cela ne répond pas complètement à la question.

EDIT: C ++ 11 & La viabilité à long terme de GCC est remise en question - si les développeurs refactorisent GCC et le rendent plus utilisable comme LLVM / clang, cela pourrait fournir un bon exemple. La discussion note que la documentation est médiocre à certains endroits, poussant la barrière d'entrée pour les nouveaux développeurs plus haut.


4

Le 3 février 2013, Michael Meeks, l'un des développeurs de LibreOffice, donne une conférence dans quelques jours intitulée "LibreOffice: nettoyer et refactoriser une base de code géante, ou pourquoi la réécrire serait encore pire . " Cela ressemble exactement à ce que vous demandez: une discussion de ce qu'ils ont fait pour prendre "une base de code gigantesque mal comprise largement commentée en allemand, sans tests unitaires, une infrastructure de construction enchevêtrée et vingt-cinq années de dette technique non acquittée "et la moderniser.

La présentation peut être diffusée en ligne et (je pense) des enregistrements seront disponibles à une date ultérieure.


1
Je me rends compte que cela est prévu dans quelques jours, mais une fois diffusé, pourriez-vous ajouter un résumé du processus qu'ils ont suivi pour moderniser leur base de code à votre réponse, au cas où ces liens disparaîtraient un jour?
Rachel

@Rachel - Si je peux capter l'émission, je le ferai certainement. Merci.
Josh Kelley

4

J'ai en fait subi une refonte assez importante trois fois dans ma carrière. Le code a tendance à se décomposer, donc si votre base de code est assez longue, un grand refactor est à peu près inévitable. Tous mes exemples étaient sur des bases de code privées, ce qui pourrait expliquer pourquoi les exemples publics sont difficiles à trouver.

La première fois était une application qui, croyez-le ou non, avait une architecture fondamentale qui ne fonctionnait qu'avec des imprimantes matricielles. Quand mon entreprise n'a plus pu trouver de fournisseur pour fournir les rubans, ils m'ont assigné pour le faire fonctionner avec une imprimante laser.

La deuxième fois a été une migration de plusieurs centaines de scripts de test automatisés de C vers Java, en partie parce que nous avions besoin d'une meilleure capacité multiplateforme et en partie parce qu'il devenait difficile d'embaucher de nouveaux développeurs C.

La troisième fois, je suis toujours en train de moduler une énorme application monolithique pour permettre les tests unitaires en réduisant le couplage et à des fins multiplates-formes.

Je compare l'effort à l'escalade d'une montagne. Vous avez cet énorme objectif devant vous, mais vous ne vous y attaquez pas au niveau macro. Vous le prenez une poignée à la fois, ayant toujours une position de repli proche, ne déconnectant jamais la sécurité précédente jusqu'à ce que la suivante soit en place. Vous commencez simplement à faire de petites améliorations incrémentielles, et après un certain temps, vous vous retournez et il y a soudain cette belle vue.

Disons que vous avez 60 000 fichiers de code fortement couplé, par exemple. Vous voulez commencer à le mettre sous test unitaire, mais les dépendances le rendent impossible. Comment le corrigez-vous? Vous découplez un fichier. Vous ajoutez des tests automatisés. Vous revenez sur un terrain stable avant de continuer. Répétez 59 999 fois.

Si simple que des sons, c'est parce qu'il est simple. Ce n'est pas facile, mais c'est simple. Il est difficile de remarquer des progrès au début. Nous sommes dans deux ans dans ce qui semblait un refactor impossible, et nous avons probablement des années devant nous jusqu'à ce que nous ayons terminé, mais en regardant en arrière, nous réalisons soudainement à quel point le code s'est déjà amélioré, et nous avons pu continuer à fournir de nouvelles fonctionnalités à nos clients en attendant.

Les deux autres fois ont fonctionné de la même manière. Vous trouvez la plus petite étape sûre que vous pouvez prendre, et vous la prenez, en gardant toujours l'application en état de fonctionnement. Vous ne vous souciez que de la vue d'ensemble pour vous assurer que vous vous dirigez dans la bonne direction. Toutes vos actions sont petites, régulières et incrémentales.


1

De mon expérience personnelle sur une base de code de plusieurs millions de lignes, j'ai trouvé quelques stratégies qui semblent fonctionner.

Regardez tous les bugs (même fermés) et essayez de les décomposer en catégories. Plus précisément pour essayer de les décomposer par le composant auquel ils appartiennent. S'ils appartiennent à plusieurs composants, notez qu'ils le font. Une fois que vous avez fait cette recherche, quel compartiment est le plus grand et utilisez-le pour déterminer par où commencer. De plus, vous pouvez consulter l'historique des révisions des fichiers pour déterminer ce qui change le plus et l'utiliser comme guide pour commencer. Fondamentalement, ce que vous essayez de faire est de trouver ce qui est le plus cassé et de répéter. De plus, j'ai constaté qu'essayer de tout réparer en même temps ne fonctionne jamais, cela provoque simplement plus de problèmes.

Si vous trouvez qu'il y a beaucoup de choses qui appartiennent à plusieurs composants, cela indique des problèmes de «système» et peut pointer vers un code trop étroitement couplé ou une API qui doit être actualisée.

Un autre domaine où j'ai passé beaucoup de temps est de tester la base de code existante. Il existe plusieurs stratégies ici et toutes ont du mérite, mais personne n'est une solution complète au problème.

  • Les tests unitaires peuvent fonctionner, mais souvent vous êtes limité à ce qui peut être testé à l'unité en raison d'un code étroitement couplé. Mais faites-le où vous le pouvez.
  • Les tests externes sont une autre avenue. Je suppose que vous l'avez probablement déjà et sinon je passerais un peu de temps à le créer. De plus, quelque chose qui a fonctionné pour moi est d'ajouter la possibilité d'injecter au hasard des défauts / événements dans le système. En plus de cela, essayez d'injecter plusieurs choses en même temps pour essayer de le faire échouer de nouvelles façons.
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.