Quand le code est-il «hérité»? [fermé]

63

Nous l'avons tous fait, nous avons étiqueté du code (souvent des éléments dont nous avons hérité) comme "hérité"? Mais il est toujours utilisé dans les systèmes de production - est-ce vraiment un héritage? Et qu'est-ce qui en fait un héritage? Devons-nous éviter cet étiquetage injustifié de code qui fonctionne parfaitement; où l’étiquetage est une pure affaire qui nous permet de faire avancer les choses et de garder les cadres supérieurs agréables et heureux?


Résumé des réponses

En regardant à travers les réponses, je vois quatre thèmes généraux. Voici ce que je vois la ventilation:

  1. N'importe quel code qui a été livré: 6
  2. Systèmes morts: 2.5
  3. Pas de tests unitaires: 2
  4. Les développeurs ne sont pas autour: 1.5
Nim
la source
1
Il s'agit d'un code hérité dès sa livraison et son fonctionnement.
Martin Beckett
23
c'est du code hérité si vous ne l'écrivez pas ;-)
Steven A. Lowe
20
Il s'agit d'un code hérité si tous ceux qui l'ont écrit sont à la retraite ou morts et si ceux qui le maintiennent le souhaitent le souhaiteraient. Sinon, cela s'appelle simplement la base de code existante.
Unpythonic
3
@ StevenA.Lowe, avec suffisamment de temps, c'est un code hérité même si je l' ai écrit.
Kyralessa

Réponses:

43

Je suis plutôt partial au résumé de Wikipedia moi-même:

Un système existant est une ancienne méthode, technologie, système informatique ou programme d'application qui continue à être utilisé, généralement parce qu'il répond toujours aux besoins des utilisateurs, même si une technologie plus récente ou des méthodes plus efficaces pour effectuer une tâche sont maintenant disponibles.

Une grande partie de ce que d'autres personnes décrivent dans leurs réponses sont les raisons pour lesquelles le code devient "hérité". Mais la question essentielle elle-même est la suivante:

Mais il est toujours utilisé dans les systèmes de production - est-ce vraiment un héritage? Et qu'est-ce qui en fait un héritage?

Le fait qu'il soit encore utilisé dans la production est précisément ce qui en fait l'héritage . Si le code ne fonctionne pas correctement ou s'il n'est plus utilisé en production, il est respectivement "cassé" ou "retiré". Legacy signifie qu'il est toujours utilisé et fonctionne correctement, mais qu'il intègre des conceptions ou des techniques qui ne sont plus d'usage courant.

Tout code ou système que vous souhaitez (a) mettre à niveau / mettre à jour, mais ne le pouvez pas, ou (b) sont en cours de mise à niveau, est un système hérité. Cela ne signifie pas une refactorisation ou un nettoyage général du code, mais des modifications significatives de la conception, en utilisant éventuellement un nouveau cadre ou même une nouvelle plate-forme.

Les systèmes ou le code peuvent devenir hérités pour un certain nombre de raisons :

  • Manque de maintenance régulière ou de logiciels pourris . Clairement, si l'application n'est pas maintenue régulièrement, elle ne suivra pas les changements majeurs du monde des logiciels. Cela peut être dû à une simple négligence ou à des choix délibérés fondés sur des priorités commerciales ou des contraintes budgétaires.

  • Manque de test. Une autre réponse fait référence à la revendication hyperbolique d'un auteur populaire selon laquelle tout code non couvert par des tests est un code hérité. Ceci est vraiment pas une définition précise , mais il est une cause possible de la racine; sans de bons tests (automatisés ou manuels), les développeurs deviennent timides et craignent d’apporter des modifications majeures car ils craignent de casser quelque chose, menant ainsi la "pourriture logicielle" décrite ci-dessus.

  • Le verrouillage des revêtements est un facteur souvent négligé qui est particulièrement insidieux dans les projets utilisant de grandes bibliothèques ou frameworks open-source (même si je l'ai déjà vu se produire avec des outils commerciaux). Souvent, des modifications importantes sont apportées au framework / bibliothèque, rendant une mise à niveau prohibitive ou difficile. Ainsi, le système devient hérité du fait qu’il fonctionne sur une plate-forme plus ancienne (et éventuellement non plus prise en charge).

  • Le code source n'est plus disponible, ce qui signifie que le système ne peut jamais être ajouté, jamais modifié. Etant donné que ces systèmes doivent être réécrits pour pouvoir être mis à niveau - et non mis à jour progressivement / de manière itérative - de nombreuses entreprises ne s’embêtent pas.

Tout ce qui ralentit ou arrête les mises à jour d'une base de code peut entraîner l'héritage de cette base de code.

Maintenant, la question distincte, non explicite mais implicite, est: qu'est-ce qui ne va pas avec le code hérité? Il est souvent utilisé comme terme péjoratif, d'où la question:

Devons-nous éviter cet étiquetage injustifié de code qui fonctionne parfaitement?

Et la réponse est non, nous ne devrions pas; l'étiquetage est justifié et le terme lui-même implique clairement un code fonctionnel. L’important n’est pas que cela fonctionne, mais comment cela fonctionne.

Dans certains cas, il n'y a rien de mal avec le code hérité. Ce n'est pas un mauvais mot. Les codes / systèmes hérités ne sont pas diaboliques. Ils ont juste collecté de la poussière - parfois un peu, parfois beaucoup.

Legacy devient obsolète lorsque le système ne peut plus répondre à tous les besoins du client. Il faut faire attention à cette étiquette. Sinon, c'est simplement une équation coûts / avantages; si le coût de la mise à niveau est inférieur au coût de ses avantages (y compris les coûts de maintenance futurs moins élevés), mettez à niveau, sinon, laissez-le tranquille. Nul besoin de cracher le mot "héritage" dans le même ton que vous réservez normalement pour "audit fiscal". C'est une situation parfaitement convenable.

Aaronaught
la source
Cela dit, le contrôle fiscal devrait être une situation tout à fait acceptable pour être aussi.
Florian Margaine
Je dirais: système qui ne peut plus être évolutif avec sa pile technologique existante.
Ramiz Uddin
40

Cela signifie généralement que cela est écrit dans un langage ou basé sur un système dans lequel vous ne faites généralement pas de nouveau développement.

Par exemple, la plupart des endroits n'écrivent pas de nouveaux programmes en Cobol. Cependant, une grande partie de leurs activités peut s'exécuter sur des applications écrites en Cobol. Par conséquent, ces applications sont étiquetées "Legacy".

Peter Mortensen
la source
Je suis d'accord avec cette réponse la plupart. Legacy consiste davantage à rester bloqué sur une plate-forme obsolète qu’à être un code ennuyeux (mais moderne) que vous ne voulez pas prendre en charge. Le code hérité est souvent assez bon (sinon personne ne s'en soucierait si vous le laissiez derrière!), Mais il est généralement associé à du matériel obsolète et à des langues / bibliothèques / bases de données obsolètes / etc.
Satanicpuppy
3
@Satanicpuppy: Je ne peux tout simplement pas accepter - j'ai déjà traité (par exemple, une partie de Java qui n'était absolument pas liée à un matériel, une bibliothèque ou une base de données en particulier), mais qui était aussi "héritée" qu'elle réécrit en Java, la langue n’était donc pas le problème non plus). J'ai aussi eu affaire à un code qui a été lié à un matériel spécifique, mais était encore seulement à peine bordure dans la catégorie « héritage ».
Jerry Coffin
4
@ jerry: Alors, qu'est-ce qui en a fait l'héritage? Legacy n'est pas synonyme de "mauvais".
Satanicpuppy
1
Dans le cas auquel je pense, il s’agissait d’un système distribué assez volumineux (construit autour de BEA Tuxedo). La conception semblait basée sur des scénarios de manuel destinés à enseigner la synchronisation en maximisant le nombre de fois / la synchronisation est nécessaire. Cela a du sens pour un manuel, mais c'est horrible pour de vrais designs. C'était assez grand pour que même la conception d'un remplacement fût un projet pluriannuel. Le remplacement a dû être effectué par phases, sans temps d'arrêt, car le système était absolument nécessaire pour l'entreprise.
Jerry Coffin
1
@Cawas: Il me semble que la réponse de @ Chad s'appliquerait si / si le nouveau système était utilisé dans un langage différent, ou si vous utilisiez un matériel différent, etc. Ceci était en cours de ré-développement en utilisant encore Java, toujours avec Tuxedo, etc. Je ne vois pas cela comme une application.
Jerry Coffin le
28

Héritage signifie tout code que vous souhaitez plutôt remplacer que le travail avec. Étant donné l'attitude de la plupart des programmeurs envers la plupart des codes existants, cela inclut généralement presque tout, à l'exception de ce que vous écrivez activement en ce moment (et d'un grand projet où vous devez coder pour une conception figée, même ce que vous écrivez au début). moment peut être inclus aussi).

  1. L'accent mis "plutôt" est destiné à transmettre ce code hérité signifie également que vous êtes coincé à le travailler, même si vous préférez ne pas le faire. Je ne suis pas sûr que l'accent ait été suffisant cependant. Les raisons peuvent varier. Certains sont vraiment trop gros et complexes à remplacer. D'autres sont des interfaces avec d'autres systèmes. D'autres encore sont motivés par la politique et les personnalités (par exemple, le code est horrible, mais le kiosque était incroyable).
  2. Un autre point sur lequel je n’ai peut-être pas suffisamment insisté est que, si la qualité du code peut être un facteur, c’est rarement (voire jamais) le seul facteur - et souvent même pas un facteur particulièrement important.
  3. Je pense que les personnes qui poussent les tests unitaires comme seul facteur déterminant sont comme le gars qui cherche la boucle d'oreille sous le réverbère, que sa femme a lâchée un pâté de maisons. La lumière est peut-être meilleure, mais vous regardez toujours au mauvais endroit. Réfléchissez avant de boire le Kool-Aid .
  4. (Un corollaire à 3.) Il me semble que certaines personnes parlent plus de la façon dont elles souhaitent que les choses soient que de la façon dont elles sont réellement. Si le jeu de la vie de John Conways pour un Apple IIc Plus n’est pas un héritage, c’est parce qu’il est suffisamment petit et simple et qu’il est facile de le ré-implémenter à partir de la base. Les tests unitaires les plus parfaits jamais écrits ne changeront pas un seul iota .

Le dernier point mène à deux autres points qui, à mon avis, sont souvent vrais.

Premièrement, le code est souvent conservé en héritage, même s'il ne devrait vraiment pas l'être. Les gestionnaires de niveau supérieur supposent généralement que la ré-implémentation d'un système coûtera autant, voire plus, que l'implémentation initiale, ce qui est rarement le cas.

Deuxièmement, les tests unitaires sont une arme à double tranchant. Ils font trop facilement croire que des changements localisés dans la mise en œuvre sont ce qui compte vraiment. Pour apporter des améliorations significatives à un système plus vaste, vous devez souvent (généralement?) Modifier suffisamment la conception globale de sorte qu'un grand nombre (sinon la plupart) des tests unitaires deviennent inutiles. Malheureusement, la présence de tests unitaires et l'attitude qu'ils engendrent peuvent rendre trop facile l'ignorance des changements réellement nécessaires.

Un exemple de cela pourrait peut-être aider: supposons qu'un programme possède une bibliothèque d' interface utilisateur avec d'excellents tests unitaires, ainsi que plusieurs programmes utilisant cette bibliothèque. Un membre de la haute direction devient convaincu que le "Web activé" est important (et, pour les besoins de l’argumentation, supposons qu’il ait raison dans ce cas-là). Après un examen attentif, les cadres intermédiaires estiment que les tests unitaires actuels suffisent pour pouvoir passer d’une interface utilisateur affichée via la fonction de fenêtrage du système d’exploitation local à un affichage à distance via HTML / CSS / AJAX, tout en conservant toute la validation d’entrée initiale.

C'est génial n'est ce pas? Cela montre à quel point les tests unitaires peuvent être utiles. Nous avons échangé l'intégralité de la mise en œuvre de l'ensemble de l'interface utilisateur, mais nous nous sommes assurés que l'apparence, la fonctionnalité et les fonctionnalités restent pratiquement cohérentes, et toutes les entrées utilisateur sont validées pour garantir l'intégrité des données. Les tests unitaires ont sauvé la journée!

Ou pas! Cette bibliothèque d’interface utilisateur extrêmement flexible et extrêmement bien testée a permis de faire comprendre à toutes les personnes impliquées que pour ce programme qui se trouve sur son marché avec ses utilisateurs, une interface utilisateur basée sur le Web est tout à fait une mauvaise chose. Ce qui est vraiment nécessaire, c'est un service Web avec une interface RESTful et aucune interface utilisateur absolue .

Maintenant, il est certainement vrai que les tests unitaires ne suppriment pas, en soi, la capacité des personnes à comprendre leur marché ou à se rendre compte que cela est vraiment nécessaire. En même temps, la vieille ligne sur les marteaux et les clous me fait presque penser. Il peut être encore pire quand vous non seulement avoir un marteau, mais ont beaucoup d'expérience avec ce marteau, et de savoir c'est vraiment un marteau de haute qualité qui fonctionne très bien dans de nombreuses situations différentes. Le fait même qu'il soit si bon dans tant de domaines dans tant de situations rend encore plus difficile la reconnaissance du fait qu'il s'agit d'un mauvais outil pour le travail à accomplir.

Jerry Coffin
la source
3
Tu vois, maintenant je ne sais pas s'il faut marquer ça ou pas, malheureusement c'est vrai, mais je me demande si c'est une attitude dont nous devons nous éloigner ...
Nim
+1 J'étais sur le point de répondre à quelque chose dans la même mesure. Héritage est tout code utilisé plutôt que activement maintenu.
Denis de Bernardy
@Nim: Je ne pense pas que ce soit une attitude dont "nous" devons nous éloigner. C'est une simple déclaration de l'évidence. :-) Pensez-y un instant et demandez-vous ce que vous considéreriez comme du code hérité si vous arriviez dans un nouvel environnement; ce sera tout sauf les nouvelles choses cool en cours de développement.
Denis de Bernardy
@ Jerry, alors vous n'aimez pas les tests unitaires? ;)
Nim
1
@Nim: Pas si - je pense qu'ils sont utiles, mais loin de la panacée comme ils sont souvent décrits.
Jerry Coffin
17

Le code hérité est généralement orphelin d'une manière ou d'une autre. Le développeur principal, le seul à l'avoir compris, a été heurté par un bus et ses notes ont été écrites dans son dialecte ukrainien, qui est maintenant une langue morte. Ou, alternativement, tout ce qui est écrit dans Visual Basic 6.0 .

Je travaille tout le temps sur le code hérité. Je dirais que les caractéristiques sont:

  • Il ne peut être prolongé sans effort massif
  • Il ne peut pas être facilement migré vers un nouveau matériel
  • Il est trop critique pour être facilement remplacé

S'il ne présente pas ces caractéristiques, il ne s'agit probablement pas d'un héritage. Si vous n'aimez pas les scripts Perl de vos prédécesseurs , je sympathise avec vous, mais je ne pense pas que ce soit un héritage. J'ai récemment modernisé un script Perl datant de 15 ans, lié à une base de données Sybase obsolète . C'était un gâteau comparé à la moindre modification apportée à notre terrible système comptable COBOL .

enfants sataniques
la source
Effrayant, notre principal développeur est également ukrainien ... haha ​​... Je suis d’accord avec la partie centrale de votre réponse, le premier point - pas tellement - je pense que cela dépend de la configuration de votre équipe de développement.
Nim
1
lol, vous avez probablement réussi à offenser (les conducteurs de bus, la langue ukrainienne et les développeurs de VB6) en un seul paragraphe. Mais bon sang j'ai ri :)
Darknight le
Je suis un voyageur temporel de 1999, vous voulez dire que Visual Basic 6 est un héritage à partir de 2011?
Hjk
@hjk Je dirais à peu près n'importe quoi après l'avènement de C # / asp.net en 2005, ce serait sur un sol fragile, mais certainement une fois la fin du support de Microsoft
annulée
12

Dans son livre, Travailler efficacement avec le code hérité , Michael Feathers définit le code hérité comme un code non couvert par les tests unitaires. C'est une définition avec laquelle je suis d'accord. Je considère également que le code existant est ancien, mais toujours utilisable.

Grant Palin
la source
24
Cela me semble être un cas de tentative de définir "tout ce qui ne suit pas la méthode que j'ai choisie" comme un "héritage". Ce n’est rien de plus ni moins qu’une tactique de débat peu coûteuse, qui consiste essentiellement à respecter la loi de Godwin et à assouplir suffisamment le langage pour empêcher les lecteurs de reconnaître immédiatement qu’il s’agit d’une attaque sans soutien (et souvent insupportable) pour quiconque ne suit pas ses préférences.
Jerry Coffin
4
@ Jerry: Je suis d'accord avec la définition de Feather. Code sans tests unitaires est une horreur à travailler avec. Si vous décidez de refactoriser certaines de ses parties pour en faciliter la raisonnement, oubliez ça! vous introduisez peut-être des bugs et le code est probablement incontrôlable, de toute façon! Je trouve que la définition de Feather n'est pas conventionnelle, mais c'est quelqu'un qui a vécu du travail avec le code hérité.
dévoré elysium
10
@devoured: les tests unitaires ne constituent pas un test décisif quant à la capacité de travailler avec du code. J'ai eu affaire à un code qui manquait de tests unitaires, mais c'était un jeu d'enfant - et à un code qui comportait des tests unitaires et qui demeurait un cauchemar. En fin de compte, les tests unitaires ne résolvent rien en eux-mêmes. Les tests unitaires pour une conception dans laquelle (par exemple) la division en unités a été mal faite peuvent toujours être totalement inutiles, et toute la conception (y compris les tests) doit être rejetée et remplacée pour produire quelque chose d'utile.
Jerry Coffin
6
Je suis d'accord avec les commentaires de Jerry. L'absence de tests unitaires n'est que l'une des nombreuses odeurs de code qui pourraient indiquer (ou non ) le mal .
smci
4
Je suis à nouveau d'accord avec la définition de Feather ainsi que dévoré. L'absence de test unitaire est primordiale car cela signifie que même le plus bel extrait de code manque ses spécifications. Les tests unitaires représentent 51% de la documentation et 100% de la spécification du code. Un code qui manque pour l'essentiel de sa documentation et de toutes ses spécifications devrait à juste titre être classé dans l'héritage.
8

Techniquement, l'héritage est tout code prêt à être écrit. Donc, dès qu’elle est en production, elle est un héritage. Parce qu'il y a déjà de la valeur là-bas, vous ne pouvez pas simplement le jeter ... Vous devez le gérer.

C'est "avant votre temps" mais "toujours votre mal de tête" .

Morons
la source
5

Le code hérité est un code qui ne reste que dans la base de code car beaucoup de choses cesseraient de fonctionner autrement. En d'autres termes: la seule raison d'être est la compatibilité ascendante.

Vous préférez le changer ou même le jeter, mais vous ne pouvez pas, car vous allez casser tout le code en vous fondant dessus (ce qui pourrait être du code que vous ne pourrez pas adapter en conséquence). Par conséquent, vous devez le conserver (et parfois même le maintenir), mais vous souhaitez que tout nouveau code ne soit pas écrit en conséquence.

Un exemple sont les méthodes obsolètes de l'API d'une bibliothèque. Ils sont toujours là, donc si ceux qui mettent à jour la bibliothèque peuvent toujours construire son projet, mais ils sont marqués comme obsolètes et votre compilateur devrait vous en avertir.

Un autre exemple concerne toutes ces astuces étranges que fait Microsoft pour exécuter des programmes écrits pour des versions de leur système d’exploitation totalement obsolètes. Le summum de cet être:

J'en ai entendu parler pour la première fois par l'un des développeurs du jeu à succès SimCity, qui m'a dit qu'il y avait un bogue critique dans son application: il utilisait la mémoire juste après l'avoir libérée, un non-non majeur qui fonctionnait correctement sous DOS, mais ne fonctionnerait pas sous Windows où la mémoire libérée risquait d’être volée immédiatement par une autre application en cours d’exécution. Les testeurs de l'équipe Windows utilisaient diverses applications populaires et les testaient pour s'assurer qu'ils fonctionnaient correctement, mais SimCity n'arrêtait pas de planter. Ils en ont informé les développeurs Windows, qui ont désassemblé SimCity, sont passés à travers celui-ci dans un débogueur, ont trouvé le bogue et ont ajouté un code spécial vérifiant si SimCity était en cours d'exécution. Dans l'affirmative, il a exécuté l'allocateur de mémoire dans un mode spécial pourrait toujours utiliser la mémoire après l'avoir libérée.
- Joel sur le logiciel

back2dos
la source
4

L'héritage implique l'héritage. Le code hérité est simplement du code hérité du passé. C'est un code hérité même si vous l'avez écrit vous-même auparavant!

Toutes les autres considérations découlent essentiellement du fait que vous ne l'avez pas écrit spécifiquement pour votre projet actuel. Ce n'est pas nécessairement une mauvaise chose en soi.

Ando
la source
Le passé pourrait être d'un jour, d'une heure ou d'un an. Cela n'en fait pas un héritage.
Vince Panuccio
2

Mon opinion est que ce qui est considéré comme un code hérité dépend de plusieurs choses et que la balise 'héritage' est probablement spécifique à une organisation.

Si le matériel / système d’exploitation sur lequel il s’exécute est ancien et n’a plus été arrêté par le fournisseur (frappe 1).

S'il est plus difficile d'essayer de le réparer que de le réécrire, pour une raison quelconque,

  • le développeur / s d'origine sont partis
  • le programme est mal écrit
  • on peut faire mieux sur une nouvelle plate-forme et cela en vaut toujours la peine pour l'entreprise

faire cela

  • la source d'origine n'est plus disponible et / ou des pièces manquantes

Frappe 2.

Une fusion de plusieurs organisations en une seule, Strike 3, va probablement devenir un héritage.

Existe-t-il une alternative plus avantageuse et moins chère vendue en tant qu'application et / ou service tiers - grève 4.

L’organisation ressemble-t-elle à un hôpital ou à un district scolaire où la cohérence est plus importante que les nouvelles technologies dans les opérations quotidiennes? Cela prendra plus de temps pour qu'une application soit considérée comme héritée par rapport à la même application dans une organisation commerciale / compétitive.

Si la société est une petite société de développement qui continue à améliorer / à soutenir l'application pour qu'elle réponde aux besoins des clients, le considère-t-il comme un code hérité ou simplement du «vieux» code? Je connais une société nommée Mc2Ok - ils ont développé le logiciel sur ce qui semble avoir été Windows 3.1 et ils ne cessent de le faire évoluer. Il a toujours beaucoup l'apparence de Windows 3.1, mais ils ont également ajouté une interface Web. Il s’agit d’une société de développement composée de deux personnes (à mon avis), et je dirais qu’en cessant de travailler dessus, ce sera considéré comme un héritage et il est temps de migrer un ou deux ans plus tard si vous l’utilisez. Mais cela pourrait être encore 10 ans ou plus.

Parfois, lorsque la gestion change, cela peut entraîner des vagues qui ont de nombreux effets de ruissellement ... En fonction de l’influence de la nouvelle gestion, il peut restituer de nombreuses applications qui pourraient autrement être héritées.

Je pense que chaque organisation doit définir ce que «code hérité» signifie pour elle. J'avais l'habitude de parcourir les petites annonces du Sunday Times chaque semaine pour voir ce que les organisations cherchaient. C'était mon baromètre de ce qui n'était plus d'actualité (l'héritage). Et bien, le Sunday Times n'est plus pertinent :-) Et nous pouvons généraliser que COBOL est un héritage, ASP Classic est un héritage, etc. Mais je pense que chaque organisation doit décider quand une application est considérée comme un héritage.

Gregory Thomson
la source
+1, bonne réponse - mieux considérer quelque chose d'héritage du point de vue de l'organisation ...
Nim
0

Le code est un héritage quand on a peur de le changer, car il peut le casser. C’est encore plus pénible lorsque l’ensemble du système risque d’être endommagé par des modifications de ce code.

C'est pourquoi je suis également d'accord avec la définition de Michael Feathers. Le code comportant de bons tests unitaires peut être modifié sans crainte.

Je pense aussi que ce code hérité n'a rien à voir avec son âge. On peut écrire le code hérité depuis le début.

komisacroS
la source