Quelqu'un pourrait-il expliquer les avantages de la suppression (ou de la conservation) du code inutilisé?

102

J'ai entendu à plusieurs reprises que le code inutilisé doit être supprimé du projet. Cependant, ce n'est pas clair pour moi "pourquoi?".

Mes points pour ne pas supprimer qui sont:

  • Le code est déjà écrit et les efforts sont dépensés
  • Le code peut être testé sur un environnement syntétique et réel
  • S'il est bien organisé (groupé, package séparé, faiblement couplé, etc.), cela ne vous dérange pas sur l'analyse globale du code ou la refactorisation
  • Le code peut être utilisé à l'avenir
  • Une fois supprimé, l'auteur peut se sentir mal à l'aise

Quelqu'un pourrait-il expliquer les avantages de la suppression (ou de la conservation) du code inutilisé?

Alex Turbin
la source
16
Le code commenté ne doit pas non plus appartenir à une base de code.
leppie
27
Parce que nous avons un contrôle de version. Si jamais nous avons besoin de faire référence à d'anciennes versions du code, nous pouvons simplement consulter l'historique.
armandino
1
Btw, se référer au contrôle de version peut être difficile, lorsque le projet est gros et que certains fichiers ont> 200 révisions
Alex Turbin
22
@AlexStamper, si vos outils ne vous permettent pas de regarder facilement les révisions passées de votre code, la solution serait d'obtenir de meilleurs outils, et non d'ajouter du bruit à votre code source.
utnapistim
1
Le génie logiciel a une question très similaire .
davidvandebunte

Réponses:

180

Voici quelques raisons pour lesquelles le code inutilisé doit être supprimé:

  • Pour toute personne qui travaille sur un projet, elle doit non seulement comprendre le code de travail, mais aussi comprendre le matériel inutilisé. C'est du temps perdu et crée de la confusion.

  • Il y a un danger qu'à un moment donné quelqu'un fasse un changement qui impliquerait par inadvertance le code «dormant» et pourrait introduire des bogues. Je sais que c'est arrivé sur des projets sur lesquels j'ai travaillé.

  • Le maintien de tout code est une charge administrative. En préservant l'ancien code redondant, ce fardeau est augmenté. Par exemple, la fusion des modifications dans la branche principale devient plus difficile car il y a plus de code à traiter et plus de possibilité de faire une erreur.

  • Ce qui se passe avec le temps, c'est que de plus en plus d'anciens codes inutilisés sont ajoutés à la base de code. Cela augmente la confusion, les malentendus potentiels et les frais généraux administratifs.

  • Les chances que le code inutilisé soit à nouveau utilisé sont très peu probables. Avec le temps, cette possibilité de réutilisation diminue. Si le code doit être supprimé et est considéré comme suffisamment important, le code peut être dérivé et documenté.

  • Tous les sentiments personnels qu'un codeur peut avoir à propos du code sur lequel il a travaillé dur sont compréhensibles. Mais une partie du professionnalisme exige que ces pensées soient mises de côté pour le mieux. Le temps ne représente personne et il n'y a pas de place pour préserver le code historique dans une base de code fonctionnelle.

suspectus
la source
26
J'ai récemment eu peur de la merde vivante en raison de la recherche de code inutilisé (sans me rendre compte qu'il était inutilisé). Le code inutilisé doit être retiré de l'existence!
leppie
1
bons points, merci. Mes collègues en ont également déclaré plusieurs
Alex Turbin
Excellente réponse. J'aimerais faire référence à des arguments comme ceux-ci dans mon mémoire de maîtrise, mais je n'arrive pas à trouver une source appropriée (livre, article, etc.). Avez-vous des pistes?
Jonas Winkler
3
Je serais très intéressé par vos raisons pour le vote défavorable tout à l'heure.
suspectus
1
Un autre point: si l'ancien code est à nouveau nécessaire, la plupart des projets utilisent de nos jours un SCM et le code peut en être extrait à nouveau (parfois avec une recherche, vrai, mais comme clairement indiqué dans la réponse, la probabilité que le code inutilisé soit nécessaire diminue à mesure que l’âge augmente).
Chop le
31

@suspectus a fait un excellent travail en présentant les raisons de la suppression du code; Je voudrais aborder vos puces individuelles pour conserver le code.

  • Le code est déjà écrit et les efforts sont dépensés

Mais si le code déjà écrit n'est pas utilisé, cela ne coûte que sans valeur (future). C’est un effort investi en vain et la préservation du produit inutilisé de ces efforts ne valide pas ces efforts. Nous gardons le code parce qu'il est utile, maintenant, et non comme une sorte de mémorial aux efforts des auteurs.

  • Le code peut être testé sur un environnement syntétique et réel

Je suis désolé, je ne sais pas ce que vous entendez par là.

  • S'il est bien organisé (groupé, package séparé, faiblement couplé, etc.), cela ne vous dérange pas sur l'analyse globale du code ou la refactorisation

S'il existe dans la base de code, aussi bien organisé soit-il, il contribue au fardeau de maintenance et de compréhension. Certes, il peut être organisé de manière à être moins un fardeau, mais s'il a disparu, ce n'est pas du tout un fardeau.

  • Le code peut être utilisé à l'avenir

Dans l'école Agile, nous disons YAGNI : You Ain't Gonna Need It. Oui, vous pourriez peut - être en avoir une utilisation dans le futur, mais nous ne pouvons pas en savoir assez aujourd'hui sur les besoins de demain pour être en mesure de prédire cela avec n'importe quel type de fiabilité. Penser autrement, c'est de l'arrogance qui tend vers l'orgueil. Ce que nous pouvons savoir sur demain, c'est: nous voulons que notre base de code soit facile à modifier, et le code inutilisé nuit à cette caractéristique.

  • Une fois supprimé, l'auteur peut se sentir mal à l'aise

L'auteur doit s'en remettre. Nous avons tous écrit des choses qui se sont avérées inutiles - il est préférable de pouvoir pointer vers un corps de code qui est entièrement utilisé (parce que la crasse inutilisée a été supprimée) que vers un corps de code dans lequel vous pouvez dire quelques méthodes, "et celle-là est effectivement utilisée!"

Carl Manaster
la source
17

N'est-il pas assez difficile de récupérer du code et de déterminer l'intention, mais maintenant vous devez déterminer quelles parties ne sont pas utilisées?

Kenny
la source
14

Le code est déjà écrit et les efforts sont dépensés

C'est également inutile. Si vous ne l'utilisez pas pour quoi que ce soit, il est (par définition) inutile, peu importe ce qu'il fait ou les efforts qui y ont été consacrés.

Le code peut être testé sur un environnement syntétique et réel

Si c'est inutile, c'est toujours inutile même si vous avez des tests dessus. Si le code est inutile, les tests devraient également être inutiles (donc garder le code commenté là, crée une ambiguïté - conservez-vous les tests? Si vous aviez le code client du code commenté, commentez-vous également le code client? )

S'il est bien organisé (groupé, package séparé, faiblement couplé, etc.), cela ne vous dérange pas sur l'analyse globale du code ou la refactorisation

Non. Tous vos outils (contrôle de source, analyse statique, extracteur de documentation, compilateur, etc.) fonctionneront plus lentement, car ils doivent traiter plus de données (et une partie plus ou moins grande de ces données est du bruit).

Si le code n'est pas bien organisé en revanche, il gâchera l'analyse statique, la refactorisation et tout autre.

Vous introduisez du bruit dans l'entrée de vos outils et espérez qu'ils y feront face correctement.

Et si votre outil d'analyse statique calcule un rapport commentaires / code? Vous venez de tout gâcher, avec quelque chose qui était pertinent jusqu'à hier (ou chaque fois que le code était commenté).

Le plus pertinent de tous, les blocs de code commentés entraînent des retards dans la compréhension du code pour la maintenance et le développement ultérieur et ces retards coûtent presque toujours cher. Posez-vous la question suivante: si vous avez besoin de comprendre l'implémentation d'une fonction, que préférez-vous regarder? deux lignes de code clair, ou deux lignes de code et vingt-six autres commentaires qui ne sont plus d'actualité?

Le code peut être utilisé à l'avenir

Si c'est le cas, vous le trouverez dans le SCM de votre équipe.

Si vous utilisez un SCM compétent et que vous comptez sur lui pour conserver le code mort (au lieu d'encombrer la source), vous devriez voir non seulement qui a supprimé ce code (auteur de la validation), mais pour quelle raison (message de validation), et quelle autre des modifications ont été apportées avec lui (le reste des différences pour ce commit).

Une fois supprimé, l'auteur peut se sentir mal à l'aise

Alors?

Vous êtes (je suppose) toute une équipe de développeurs qui est payée pour créer le meilleur logiciel que vous savez faire, pas "le meilleur logiciel que vous savez faire sans blesser les sentiments de X".

C'est une partie de la programmation, que la plupart du code écrit sera finalement jeté; par exemple, Joel Spolsky a déclaré à un moment donné que pour son entreprise, environ 2% du code écrit est produit.

Si vous privilégiez l'ego des développeurs à la qualité de la base de code, vous sacrifierez la qualité de votre produit, pour ... quoi exactement? Préserver l'immaturité de vos collègues développeurs? Protéger les attentes irréalistes de vos collègues?

Edit: J'ai vu une raison valable de laisser du code commenté dans la source, et c'est un cas très spécifique: lorsque le code est écrit sous une forme étrange / non intuitive et que la manière propre de le réécrire ne le fait pas travailler pour une raison vraiment subtile. Cela ne doit également être appliqué qu'après une tentative répétée pour corriger le problème et chaque fois que la tentative a réintroduit le même défaut. Dans un tel cas, vous devez ajouter le code intuitif commenté en tant que commentaire et expliquer pourquoi cela ne fonctionne pas (afin que les futurs développeurs ne tentent pas à nouveau le même changement):

// note by <author>: the X parameter here should normally
// be a reference:
// void teleport(dinosaur& X);
// but that would require that we raise another dinosaur and
// kill it every twelve hours
// as such, the parameter is passed by value
void teleport(dinosaur X);
utnapistim
la source
10

Le code mort pollue votre code

Le code mort diminue la compréhensibilité et la lisibilité.

Les meilleurs codes sont toujours réutilisés, et si vous avez des codes morts, cela réduit la réutilisabilité

Nous sommes motivés par une approche modulaire du codage, où nous concevons des codes pour l'interaction avec nos collègues programmeurs, et non pour une machine. Nous devons mettre le plus d'énergie pour lui permettre de comprendre notre code. La machine ira de toute façon bien.

Le code mort ou commenté est comme de faux panneaux de signalisation qui ne font que confondre les gens, alors évitez-le à tout prix.

Jimmy
la source
10
  • La peur . Cela rend l'équipe plus inquiète et produit moins. La quantité de peur augmente de façon exponentielle lorsque plus de code mort est introduit. "Nous ne savons pas si ce bit est utilisé, donc nous n'osons pas le retirer ou le toucher."
  • Des changements radicaux . Si quelque chose qui doit être changé partout dans le système existe également dans le code mort, le changez-vous? Il est très difficile de savoir s'il n'est définitivement pas utilisé quelque part, c'est donc toujours un risque. Et même si cela ne cassait rien, le code mort fonctionnerait-il du tout s'il était repris après ce changement?

    Lorsqu'il s'agit d'un changement radical, les développeurs devront également vérifier chaque endroit contenant le code et dans le cas d'un code mort, cela est redondant. Et les vérifier prend plus de temps lorsque le code est mort car il est difficile de vérifier qu'il n'est utilisé nulle part.

  • Charge mentale . Chaque fois que vous devez vous demander si quelque chose est utilisé ou si vous devez faire quelque chose au code mort, cela prend une partie de votre cerveau.
  • L'oie sauvage poursuit . "J'ai besoin d'un exemple sur la façon d'utiliser Foobar. Oh, c'est à ces endroits dans la base de code. Je vais vérifier le premier hit et découvrir où il se trouve dans l'interface utilisateur. Hmm ... Je ne le trouve nulle part."
  • Rapports gonflés (par exemple, combien de lignes de code, classes, routines, changements). Déforme la visibilité du projet et les décisions sur les parties de la base de code sur lesquelles travailler et les estimations des projets futurs.
  • Confiance affaiblie sur la base de code . Cela peut entraîner plus de temps passé sur des tâches redondantes et interrompre le flux d'utilisation de la base de code. Les développeurs devront peut-être vérifier très soigneusement que tout ce qu'ils utilisent fonctionnera comme ils le pensent.

C'est extrêmement précieux si vous savez qu'une partie de la base de code n'est pas utilisée car vous pouvez la supprimer. Si vous le laissez rester, à l'avenir, il peut être difficile, voire impossible, d'être certain qu'il n'est pas utilisé. Par exemple, certaines des choses qui utilisent le code de manière surprenante: réflexion, appel dynamique de routines concaténées à partir de chaînes, eval, framework magic .

Cependant, s'il y a une forte probabilité que le code soit utilisé à l'avenir, il est plus facile de l'ajouter s'il se trouve juste là avec l'autre code plutôt que dans le système de contrôle de version. Il se peut que vous ne vous souveniez pas des mots que le code contenait après un certain temps, il peut donc être très difficile de trouver le code dans les entrailles du VCS. Mais je laisserais le code mort exister rarement et même dans ce cas, je commenterais le code.

Heikki Naski
la source
4
  • Le code inutilisé est un espace de recherche plus grand pour que vous puissiez le lire et pour tout autre élément qui analyse généralement votre code. Par exemple, un compilateur, un IDE, rechercher dans un fichier, débogage, analyse statique, plus à revoir, inclusion de fichier, extraction de VCS, etc. Cela ralentit ces processus et ajoute un bruit significatif.
  • Le code inutilisé n'est pas toujours un code mort. Il peut s'exécuter dans certaines circonstances. Cela peut non seulement offrir un vecteur de bogues et de problèmes de performances, mais peut également être un problème de sécurité. En ce qui concerne les performances, cela peut s'exprimer de manière inattendue, comme des téléchargements plus importants.
  • Le code inutilisé engendre du code inutilisé. Si vous supprimez un appel de fonction, puis recherchez des utilisations de cette fonction pour voir si elle est toujours nécessaire, vous pouvez voir une correspondance du code inutilisé précédent et supposer que vous pouvez la conserver. Plus vous avez de code inutilisé, plus il y a de sauts pour déterminer si le code n'est pas utilisé.
  • Le code inutilisé finit souvent par devoir être maintenu. Disons que A et B dépendent de C. Parmi ceux-ci, B n'est pas utilisé. Vous changez C, puis B ne compilera pas parce que vous avez supprimé un membre d'une structure en C que B avait besoin, maintenant vous devez corriger B ou le supprimer activement de la compilation. Vous auriez dû simplement le supprimer.

Cette liste peut sembler simple, mais chacun de ces éléments se manifeste de centaines de façons différentes, ajoutant une traînée qui synergise tout au long du processus de développement. L'inefficacité peut souvent être prouvée ou démontrée d'une manière simple et mathématique.

En réponse à vos points ...

  • Le code est déjà écrit et les efforts sont dépensés

Mais il doit souvent être maintenu. Il apparaîtra également toujours dans des éléments tels que la recherche dans le fichier.

  • Le code peut être testé sur un environnement syntétique et réel

Je ne sais pas ce que vous entendez par celui-ci. Je pense que c'est le même que le dernier. Vous voulez dire que le code est déjà testé et que son nettoyage peut nécessiter un nouveau test. C'est un coût qui en vaut généralement la peine car il sera rentable 90% du temps et pour éviter qu'il aurait dû être nettoyé avant de passer en production. Presque tout le code a deux itérations, faites-le fonctionner, nettoyez-le. La raison pour laquelle il faut être testé deux fois est que quelqu'un a sauté la dernière étape. Si votre code est également trop cher pour relire le diff, tester (ce qui est probablement le cas s'il contient beaucoup de code inutilisé), etc., c'est un autre problème.

  • S'il est bien organisé (groupé, package séparé, faiblement couplé, etc.), cela ne vous dérange pas sur l'analyse globale du code ou la refactorisation

Votre code devrait être comme ça de toute façon, mais cela n'atténue que modérément le problème. C'est l'argument le plus étrange d'entendre que quelque chose doit être organisé mais impur. Il est normal d'essayer de garder le code modulaire et de réduire les dépendances, mais vous voulez également du code réutilisable et si tous vos modules sont un îlot, il y a de fortes chances que vous n'ayez pas été à sec. Vous pouvez également vous retrouver à faire un découplage excessif qui ne fait rien mais atténue le problème du code désordonné inutilisé.

  • Le code peut être utilisé à l'avenir

Beaucoup de gens apprécient le code écrit. S'il n'est pas utilisé maintenant, c'est un poids mort et en réalité, lorsque vous empruntez ce chemin, seule une fraction du code inutilisé devient du code utilisé. Selon toute probabilité, le code inutilisé ne sera probablement pas du code utilisable ou utilisé. Le code le plus susceptible d'être réutilisé est le code déjà utilisé qui fait quelque chose.

Ce qui est pire, c'est que le code inutilisé n'a pas de but. Quand quelqu'un arrive et doit changer quelque chose qui finit par avoir un impact sur le code inutilisé, il sera perplexe assis là à essayer de comprendre ce que ce code inutilisé n'a pas besoin de faire.

Il est facile pour les gens de ressentir cela lorsqu'ils se lancent dans le code, cela demande beaucoup d'efforts. Une fois maîtrisé et habitué, le code devient comme faire du vélo. Vous constaterez que le coût de l'écriture d'un tel morceau de code s'effondre, le coût de sa maintenance augmente.

  • Une fois supprimé, l'auteur peut se sentir mal à l'aise

C'est le problème de l'auteur. D'une part, il est égoïste de laisser des tonnes de code inutilisé que d'autres doivent gérer. D'un autre côté, si un auteur met ses sentiments sur la qualité du code, il ne devrait probablement pas coder. Vous allez sur la route avec cela, vous ne pouvez pas réparer leur code quand il est cassé parce que cela blessera leurs sentiments. Ce n'est pas un bon signe si quelqu'un est attaché au code simplement parce qu'il lui appartient plutôt que parce qu'il est bon. Un auteur doit se sentir heureux que son code soit nettoyé. C'est comme si quelqu'un sortait votre poubelle pour vous et la jetait à la poubelle.

Je serais aux anges si quelqu'un faisait ça pour moi. Ce qui pourrait vous aider à surmonter ces sentiments, c'est au lieu d'attendre que quelqu'un d'autre le fasse, essayez de le faire vous-même. Continuez à réécrire de manière itérative un morceau de code que vous avez fait, en le rendant plus performant, concis, avec moins d'excès et plus flexible mais avec moins de code à chaque fois. Essayez de ne pas vous sentir satisfait de la quantité de code, mais de tout ce que vous pouvez réaliser avec si peu de code. C'est grinçant de monter de niveau et une fois que vous faites cela, tout votre code sortira à un bon niveau, il n'aura donc pas besoin d'être mis à niveau aussi souvent.

jgmjgm
la source
3

Tout d'abord, vous devez toujours utiliser un outil de contrôle de code source pour gérer vos projets. Par conséquent, la suppression du code inutilisé est une bonne pratique car vous pouvez toujours revenir en arrière en utilisant le contrôle de code source pour obtenir le code supprimé. Pour moi, la raison de supprimer le code inutilisé est que seule la personne qui sait que le code est inutilisé le sait, quelqu'un d'autre dans l'équipe rencontrera ce code et essaiera de comprendre ce qu'il fait et comment il s'intègre dans l'ensemble de l'application et sera déçu après tant d'efforts que le code n'est pas du tout utilisé :)

Ankur
la source
3

Cette discussion date de plusieurs années, mais je viens de la rencontrer ...

Une chose que je n'ai pas vu mentionnée est le travail qui doit être effectué pour supprimer le code inutilisé. Dans de nombreux cas, le temps et les efforts nécessaires pour supprimer le code inutilisé ne sont pas de nature triviale, et il y a généralement des coûts supplémentaires pour tester et documenter le système refactorisé. Juste une autre chose à considérer dans le processus de décision.

RonE
la source
2

Je pense que vous pouvez avoir deux cas: - code d'application: s'il est inutilisé peut-être qu'il n'est pas testé et non maîtrisé au fil du temps, peut-être que vous pouvez passer à un "référentiel de code interne" - code API: si vous écrivez une bibliothèque alors à mon humble avis c'est un meilleur choix pour le maintenir mais dans votre processus de développement actif

Antonello Pasella
la source
2

Êtes-vous sûr que le code n'est pas utilisé?

Il ne suffit pas de vérifier le code encore compilé. En C ++, si vous supprimez une méthode implicitement définie «inutilisée» comme operator=si vous n'obtiendrez pas d'erreur de compilation, la classe commencera simplement à utiliser une implémentation par défaut (potentiellement incorrecte). En Java ou C #, le code peut être utilisé par réflexion. Dans les langages orientés objet, l'héritage peut jouer un rôle (la classe de base peut maintenant être appelée). Dans presque toutes les langues, une autre fonction surchargée peut avoir pris le relais.

Vérifiez l'âge du code dans le contrôle de version, pas seulement qu'il n'est pas utilisé. J'ai vu du code qui avait l'air inutilisé mais qui venait juste d'être validé et qui était en fait la première étape d'un projet d'un autre développeur.

Supprimer agressivement le code inutilisé

Vous payez pour maintenir le code:

  • Correction des builds cassés (temps d'ingénierie). Nous avons récemment eu une chaîne de #includechangements compliquée , introduisant une nouvelle surcharge du code inutilisé, entraînant un mal de tête de taille raisonnable pour chaque ingénieur d'une équipe de dizaines de développeurs.
  • Dans les ressources machine sur les tests (en supposant que vous ayez des builds continus auto-testés). Mon équipe a récemment examiné tous nos tests les plus lents, et beaucoup d'entre eux étaient sur du code autrement inutilisé. Les ingénieurs exécutant des tests localement ou dans le cadre d'une intégration continue attendent des tests sur du code inutilisé.
  • En termes de lisibilité (temps d'ingénierie à nouveau). Vos fichiers d'en-tête représentent une API. S'ils incluent des fonctions que personne ne voudrait utiliser mais que tout le monde doit lire, la courbe d'apprentissage de votre code est d'autant plus difficile.
  • Dans les recherches de code (temps d'ingénierie à nouveau). Souhaitez-vous nettoyer votre maison, votre disque dur ou Google Drive? Plus vous recherchez un domaine, plus il est important qu'il ait un contenu pertinent pour éviter les faux positifs (ou vous utilisez une recherche plus sophistiquée comme un moteur de recherche Web).

Je dirais que pratiquement tout le code que le développeur moyen écrit devient inutilisé sur un horizon de cinq ans, de sorte que cette activité ne s'arrête jamais . Ne laissez pas cela être vous; n'écrivez que du code de haute qualité et absolument nécessaire.

davidvandebunte
la source