Quels sont les points clés pour travailler efficacement avec le code hérité? [fermé]

133

J'ai déjà vu le livre Travailler efficacement avec Legacy Code recommandé à plusieurs reprises. Quels sont les points clés de ce livre?

Y at-il beaucoup plus à faire avec le code hérité que d’ajouter des tests unitaires / d’intégration et ensuite de refactoriser?

Armand
la source
2
Bien sûr, l’essentiel est d’ajouter des tests puis un refactor. Le livre traite en grande partie de la façon dont vous réussissez à obtenir du code incroyablement compliqué à tester, et il y a beaucoup de révélateurs sur ce point. Disons simplement que Feathers ne fait pas de prisonniers!
Kilian Foth
9
Vous devriez peut-être lire le livre
HLGEM,
Belle critique ici: andreaangella.com/2014/03/…
rohancragg

Réponses:

157

Le problème clé du code hérité est qu’il n’a pas de test. Vous devez donc en ajouter (et plus encore ...).

Cela en soi prendrait beaucoup de travail, comme @mattnz l'a noté. Mais le problème particulier du code existant est qu’il n’a jamais été conçu pour être testé . En règle générale, il s’agit d’un énorme gâchis complexe de codes spaghetti, dans lequel il est très difficile, voire impossible, d’isoler les petites pièces à tester. Donc, avant de tester les unités, vous devez reformuler le code pour le rendre plus testable.

Cependant, pour pouvoir refactoriser en toute sécurité, vous devez passer des tests unitaires afin de vérifier que rien n'a été cassé avec vos modifications ... Il s'agit de la capture 22 du code hérité.

Le livre vous apprend à sortir de cette situation en apportant les modifications minimales, les plus sûres, au code, juste pour activer les premiers tests unitaires. Celles-ci ne sont pas conçues pour rendre la conception plus agréable, mais uniquement pour permettre des tests unitaires. En fait, ils rendent parfois le design plus laid ou plus complexe. Cependant, ils vous permettent d’écrire des tests - et une fois que vous avez mis en place des tests unitaires, vous êtes libre d’améliorer la conception.

Il existe de nombreuses astuces pour rendre le code testable - certaines sont évidentes, d'autres pas du tout. Il y a des méthodes que je n'aurais jamais pensé à moi-même sans lire le livre. Mais ce qui est encore plus important, c’est que Feathers explique en quoi une unité de code peut être testée. Vous devez couper les dépendances et introduire des barrières dans votre code, mais pour deux raisons distinctes:

  • détection - afin de vérifier et de vérifier les effets de l'exécution d'un morceau de code, et
  • séparation - afin d’obtenir d’abord le code spécifique dans un harnais de test.

Réduire les dépendances en toute sécurité peut être délicat. L'introduction d'interfaces, de simulacres et d' injection de dépendance est un objectif simple et agréable, mais qui n'est pas nécessairement sans danger pour le moment. Nous devons donc parfois recourir à la sous-classe de la classe testée afin de remplacer une méthode qui normalement déclencherait par exemple une demande directe à une base de données. D'autres fois, nous pourrions même avoir besoin de remplacer une classe de dépendance / jar par une fausse dans l'environnement de test ...

Pour moi, le concept le plus important introduit par Feathers sont les coutures . Une couture est un endroit dans le code où vous pouvez changer le comportement de votre programme sans modifier le code lui-même . Construire des coutures dans votre code permet de séparer le code sous test, mais également de détecter le comportement du code sous test même lorsqu'il est difficile ou impossible de le faire directement (par exemple parce que l'appel modifie un autre objet ou sous-système , dont l’état n’est pas possible d’interroger directement à partir de la méthode de test).

Cette connaissance vous permet de remarquer les germes de la testabilité dans le plus méchant tas de code et de rechercher les modifications minimales, les moins gênantes et les plus sûres pour y parvenir. En d'autres termes, pour éviter de faire des refactorisations "évidentes" qui risquent de rompre le code sans vous en rendre compte - car vous n'avez pas encore les tests unitaires pour le détecter.

Péter Török
la source
5
Notez que lorsque la réponse ci-dessus dit "tests unitaires", cela signifie en fait "tests automatisés" . Pour une application existante, une grande partie des tests automatisés initialement utiles sont en fait des tests d'intégration (où la logique de test exécute une plus grande dalle du code global et peut produire des défaillances dues à des défauts dans de nombreux endroits différents), plutôt qu'en unités réelles . des tests (qui visent à analyser un seul module et à exécuter des parties beaucoup plus petites du code).
Lutz Prechelt le
99

Des moyens rapides pour obtenir les points clés du travail efficace avec le code hérité

MarkJ
la source
3
Le lien MP3 sur cette page Hanselminutes est cassé, mais celui sur hanselminutes.com/165/… n'est pas - s3.amazonaws.com/hanselminutes/hanselminutes_0165.mp3 .
Peter Mortensen
Merci rosston pour la correction du lien PDF. On dirait que objectmentor.com a disparu - peut-être qu'Oncle Bob a cessé ses activités?
MarkJ
Je ne suis pas sûr de savoir ce qui est arrivé à un mentor, mais ces derniers temps, oncle Bob travaille pour 7th Light.
Jules
40

Je travaille sur une base de code contenant des millions de lignes de code, certaines remontant aux années 1980. Il ne s'agit que de logiciels. Il suffit donc de rédiger quelques tests unitaires pour pouvoir les reformuler et les améliorer.

Le mot clé ici est juste - c'est un mot de quatre lettres qui n'appartient pas au vocabulaire des programmeurs, sans parler de celui qui travaille sur des systèmes hérités.

Combien de temps pensez-vous qu'il faut pour écrire un test unitaire, pour tester une heure d'effort de développement? Pour la discussion, disons une heure de plus.

Combien de temps est investi dans ce système hérité vieux de 20 millions d'années? Disons que 20 développeurs pendant 20 ans multiplient les 2000 heures / an (ils ont travaillé assez dur). Choisissons maintenant un numéro - vous avez de nouveaux ordinateurs et de nouveaux outils, et vous êtes tellement plus intelligent que les gars qui ont écrit ce morceau de $% ^^ en premier lieu - disons que vous en valez 10. Avez-vous 40 années-hommes, eh bien, avez-vous ...?

Donc, la réponse à votre question est qu'il y a beaucoup plus. Par exemple, cette routine de 1 000 lignes (quelques-unes en compte plus de 5 000) est excessivement complexe et constitue un morceau de spaghetti. Il suffirait (encore un mot de quatre lettres) de quelques jours pour le re-factoriser en quelques routines de 100 lignes et quelques aides de 20 lignes supplémentaires, non? FAUX. 100 corrections de bogues sont cachées dans ces 1000 lignes, chacune correspondant à une exigence utilisateur non documentée ou à un cas obscur. C'est 1000 lignes parce que la routine d'origine de 100 lignes n'a pas fait le travail.

Vous devez travailler avec l'état d'esprit " si ce n'est pas cassé, ne le répare pas ". Quand il est cassé, vous devez être très prudent lorsque vous le corrigez - car vous améliorez les choses, vous ne changez pas accidentellement autre chose. Notez que "cassé" peut inclure du code non maintenable, mais fonctionnant correctement, qui dépend du système et de son utilisation. Demandez «Qu'est-ce qui se passe si je gâche ça et que j'aggrave la situation?», Car vous le ferez un jour et vous devrez dire au patron des patrons pourquoi vous avez choisi de le faire.

Ces systèmes peuvent toujours être améliorés. Vous aurez un budget, un calendrier, peu importe. Si vous ne le faites pas, allez en fabriquer un. Arrêtez de faire mieux quand l'argent / le temps est écoulé. Ajoutez une fonctionnalité, donnez-vous le temps de l'améliorer. Corrigez un bogue - encore une fois, passez un peu plus de temps et améliorez-le. Ne livrez jamais pire que ce que vous aviez commencé.

Mattnz
la source
2
Merci pour les conseils! Sont-ils les vôtres ou du livre?
Armand
3
Probablement un peu des deux - j'ai lu le livre après quelques années de travail, et je devrais probablement le lire encore une fois. Comme tout bon livre, cela vous obligera à contester une partie de ce que vous êtes en train de faire, à renforcer la plupart de ce que vous faites, mais vous n'aurez pas toutes les réponses à vos problèmes spécifiques.
mattnz
7
"C’est 1000 lignes parce que la routine originale 100 lignes n’a pas fait le travail." Cela semble donc très rarement être le cas. Plus souvent qu'autrement, c'est 1 000 lignes simplement parce que le développeur d'origine s'est retroussé les manches et a commencé à coder avant même d'épargner un moment de planification ou de conception.
Stephen Touset
3
Non, je dis que dans la plupart des cas (que j'ai personnellement rencontrés), des routines de 1 000 lignes indiquent clairement que les gens ont commencé à écrire du code avant de penser à la manière d'écrire une abstraction appropriée. Les routines de milliers de lignes sont, par définition, pratiquement trop compliquées. Etes-vous en train de dire qu'une routine de mille lignes avec des centaines de corrections de bogues cachées et non commentées est la marque d'un développeur responsable?
Stephen Touset
16
Si vous avez cru chaque message de ce site, tout le monde doit composer avec un code de 1 000 lignes de spaghettis, mais personne ne l’a jamais écrit. D'après mon expérience, 1000 (et 10000) routines de lignes sont la marque des développeurs qui font de leur mieux avec ce qu'ils ont pour offrir ce que leur demande le patron qui paie leur salaire. Je trouve insultant et arrogant la façon dont tant de développeurs se sentent libres de faire des commentaires marginaux sans avoir la moindre idée des circonstances, sans jamais avoir à exposer leurs propres travaux à la communauté.
mattnz
19

Il faut retenir deux points essentiels du livre.

  1. Le code hérité est tout code qui n'a pas de couverture de test.
  2. Chaque fois que vous devez modifier le code existant, vous devez vous assurer qu'il est couvert.

Comme d'autres intervenants l'ont fait remarquer, essayer de mettre à jour de manière préventive votre code existant est une tâche insensée . Au lieu de cela, chaque fois que vous devez apporter une modification au code hérité (pour une nouvelle fonctionnalité ou une correction de bogue), prenez le temps de supprimer son statut hérité.

Michael Brown
la source
6
+1 Excellent point: "Chaque fois que vous devez modifier le code hérité, prenez le temps de supprimer son statut."
Jean
3
Suppression du statut Legacy, je vais voter :)
Rachel
7

En un mot, c’est vrai: ajouter des tests et une refactorisation, c’est l’essentiel.

Mais le livre vous propose de nombreuses techniques différentes pour le faire avec un code très difficile à tester et à refactoriser en toute sécurité.

Oded
la source