Vous avez trouvé du code qui semble superflu et le compilateur ne le remarque pas. Que faites-vous pour être sûr (ou aussi proche que possible) que la suppression de ce code ne provoquera pas de régression.
Deux idées me viennent à l’esprit.
"Simplement", utilisez la déduction selon que le code doit ou non être exécuté. Toutefois, il peut parfois s’avérer un travail complexe et fastidieux, légèrement risqué (votre évaluation est entachée d’erreurs) sans aucun retour sur investissement substantiel.
Placez la connexion dans cette section de code et voyez à quelle fréquence il est entré dans la pratique. Après suffisamment d'exécutions, vous devriez avoir une confiance raisonnable. Retirer le code est sans danger.
Y at-il de meilleures idées ou quelque chose comme une approche canonique?
la source
Réponses:
Dans mon monde imaginaire parfait où je suis couvert à 100% par les tests unitaires, je le supprime, je fais mes tests unitaires et, quand aucun test ne passe au rouge, je le valide.
Mais malheureusement, je dois me lever tous les matins et faire face à la dure réalité: beaucoup de codes n’ont pas de tests unitaires ou ne sont pas fiables. Ils ne peuvent donc pas faire confiance à tous les cas possibles. Donc, je considérerais le risque / récompense et arriverais à la conclusion que cela ne vaut tout simplement pas la peine:
la source
Ce processus comporte deux moitiés. La première consiste à confirmer que le code est bien mort. La seconde consiste à comprendre les coûts de l'erreur et à veiller à ce qu'ils soient correctement atténués.
Beaucoup de réponses ici ont d'excellentes solutions à la première moitié. Des outils tels que les analyseurs statiques sont parfaits pour identifier le code mort.
grep
peut être votre ami dans certains cas. Une démarche inhabituelle que je prends souvent consiste à essayer d'identifier le but initial du code. Il est beaucoup plus facile de dire «X n'est plus une fonctionnalité de notre produit et le segment de code Y a été conçu pour prendre en charge la fonctionnalité X» plutôt que de dire «Je ne vois aucune utilité pour le segment de code Y».La seconde moitié est une étape clé pour résoudre tout problème lié à la suppression du code. Vous devez comprendre quelles sont les implications d'une réponse fausse. Si des gens vont mourir si la réponse est fausse, faites attention! Peut-être que c'est un bon moment pour accepter que le code cruel se développe avec le temps et essayer plutôt de ne pas écrire plus cruellement. Si les gens ne vont pas mourir, demandez-vous comment vous pardonnez à vos utilisateurs. Pouvez-vous leur envoyer un correctif si vous avez cassé quelque chose et entretenez vos relations avec la clientèle? Avez-vous une équipe Q & R qui est payée pour trouver des problèmes comme celui-ci? Ces questions sont essentielles pour comprendre votre degré de certitude avant d'appuyer sur la touche Suppr.
Dans les commentaires, rmun a souligné une excellente formulation du concept de compréhension de l'objectif initial du code avant de le supprimer. La citation est maintenant connue sous le nom de Clôture de Chesterton . Bien qu’il soit trop volumineux pour être cité directement dans un commentaire, je pense qu’il mérite d’être cité correctement ici:
la source
J'ai aussi tendance à
grep
rechercher le nom de fonction / classe dans le code, ce qui peut apporter des avantages supplémentaires à un analyseur de code, comme si le nom est mentionné dans un commentaire, dans un fichier de documentation ou dans un script, par exemple. Je lance grep sur les fichiers de l’arborescence des sources et stocke le résultat dans un fichier; généralement, le résultat donne une information condensée: nom / chemin du fichier, numéro de ligne et la ligne où le nom est rencontré, ce qui peut donner des indices sur l'endroit où la fonction / la classe est appelée ou mentionnée sans aucune signification sémantique (contrairement à un analyseur de code ) et quelles que soient les extensions de fichier. Ce n'est certainement pas la solution ultime, mais une belle addition à une analyse.la source
$object->$variableMethod($arg1, $arg2);
grep
ing le. La fonction englobant la section de code peut donner des indices sur la manière dont la fonction est utilisée et donc sur son contenu.la source
En plus des réponses existantes mentionnées, vous pouvez également supprimer le code de plusieurs versions de manière itérative.
Dans la version initiale, vous pouviez émettre un avertissement de dépréciation avec le bloc de code toujours actif. Dans la version ultérieure, vous pouvez supprimer le bloc de code mais laisser un message d'erreur permettant aux utilisateurs de constater que la fonctionnalité est obsolète et n'est plus disponible. Dans la version finale, vous supprimeriez le bloc de code et tous les messages.
Cela peut aider à identifier des fonctionnalités imprévues sans prévenir les utilisateurs finaux. Dans le meilleur des cas, le code ne fait vraiment rien et tout ce qui se passe est que le code inutile est conservé sur plusieurs versions avant d'être supprimé.
la source
Beaucoup de gens suggèrent que la chose "sûre" est de laisser le code dedans si vous ne pouvez pas prouver qu'il est inutilisé.
Mais le code n'est pas un atout, c'est un passif.
À moins que vous ne puissiez expliquer pourquoi c'est important et indiquer ses tests, l'alternative "plus sûre" pourrait très bien être de le supprimer.
Si vous n'êtes toujours pas sûr, assurez-vous au moins d'ajouter des tests pour exercer le code zombie.
la source
Vous pouvez utiliser les options pour changer le chemin d’exécution de votre logiciel afin d’ignorer complètement le code en question.
De cette façon, vous pouvez déployer votre modification en toute sécurité avec le code non utilisé et la bascule désactivée. Si vous remarquez des erreurs majeures liées au code, réactivez la bascule et analysez le chemin possible.
Cette approche devrait vous donner confiance si vous ne voyez aucun problème sur une période prolongée, ainsi que la possibilité de la réactiver en cas de déploiement en temps réel. Cependant, une solution encore meilleure consisterait également à appliquer une couverture supplémentaire de journalisation et de test autour de la zone en question, ce qui fournira davantage de preuves quant à son utilisation ou non.
En savoir plus sur les bascules ici: https://martinfowler.com/articles/feature-toggles.html
la source
L'analyse statique bien sûr ... et la bonne chose est que vous n'avez pas besoin de nouveaux outils; votre compilateur dispose de tous les outils d'analyse statique dont vous avez besoin.
Il suffit de changer le nom de la méthode (par exemple, changer
DoSomething
enDoSomethingX
) et ensuite exécuter une construction.Si votre construction réussit, la méthode, évidemment, n'est utilisée par rien. Coffre-fort à supprimer.
Si votre construction échoue, isolez la ligne de code qui l'appelle et vérifiez quelles
if
instructions entourent l'appel afin de déterminer comment le déclencher. Si vous ne trouvez aucun cas d'utilisation de données susceptible de le déclencher, vous pouvez le supprimer en toute sécurité.Si vous souhaitez vraiment le supprimer, pensez à conserver le code, mais en le marquant avec un ObsoleteAttribute (ou l’équivalent dans votre langue). Libérez-le comme cela pour une version, puis supprimez le code après qu'aucun problème n'ait été trouvé dans la nature.
la source
la source
Supprimer le code inaccessible
Dans un langage basé sur des principes statiques, vous devez toujours savoir si le code est réellement accessible ou non: supprimez-le, compilez-le. S'il n'y a pas d'erreur, il n'est pas accessible.
Malheureusement, toutes les langues ne sont pas typées statiquement, et toutes les langues statiquement typées ne sont pas régies par des principes. Les choses qui pourraient mal tourner incluent (1) la réflexion et (2) la surcharge sans principes.
Si vous utilisez un langage dynamique ou un langage avec une réflexion suffisamment puissante pour que l'élément de code examiné puisse éventuellement être consulté au moment de l'exécution via la réflexion, vous ne pouvez pas vous fier au compilateur. Ces langages incluent Python, Ruby ou Java.
Si vous utilisez une langue avec une surcharge sans principe, le simple fait de supprimer une surcharge peut simplement changer la résolution de la surcharge en une autre surcharge en mode silencieux. Certains de ces langages vous permettent de programmer un avertissement / une erreur de compilation associé à l'utilisation du code, sinon vous ne pouvez pas compter sur le compilateur. Ces langages incluent Java (utilisation
@Deprecated
) ou C ++ (utilisation[[deprecated]]
ou= delete
).Donc, à moins que vous ne soyez très chanceux de travailler avec des langages stricts (on pense à Rust), vous pouvez vraiment vous tirer une balle dans le pied en faisant confiance au compilateur. Et malheureusement, les suites de tests sont généralement incomplètes, donc pas beaucoup plus d’aide non plus.
Cue la prochaine section ...
Supprimer le code potentiellement inutilisé
Plus probablement, le code est effectivement référencé, mais vous soupçonnez qu'en pratique les branches de code qui le référencent ne sont jamais prises.
Dans ce cas, peu importe la langue, le code est manifestement accessible et seule une instrumentation d'exécution peut être utilisée.
Dans le passé, j'ai utilisé avec succès une approche en trois phases pour supprimer ce code:
C'est quoi un cycle? C'est le cycle d'utilisation du code. Par exemple, pour une application financière, je m'attendrais à un cycle mensuel court (avec les salaires versés à la fin du mois) et à un cycle annuel long. Dans ce cas, vous devez attendre au moins un an pour vérifier qu'aucun avertissement n'est émis pour l'inventaire de fin d'année. Il peut utiliser des chemins de code qui, autrement, ne sont jamais utilisés.
Espérons que la plupart des applications ont des cycles plus courts.
Je conseille de mettre un commentaire TODO, avec une date, indiquant quand passer à la prochaine étape. Et un rappel dans votre calendrier.
la source
[[deprecated]]
identifiant les sites qui appellent cette version; vous pouvez ensuite les inspecter pour voir si leur comportement va changer. Vous pouvez également définir votre surcharge de la manière suivante= delete
: dans ce cas, vous devrez explicitement transtyper des arguments pour utiliser l'une des autres versions.Retirer le code de la production revient à nettoyer une maison. Au moment où vous jetez un objet du grenier, votre femme vous tuera le lendemain pour avoir jeté le cadeau de retour au pays du troisième neveu de son arrière grand-mère à son voisin décédé en 1923.
Sérieusement, après une analyse sommaire à l'aide de divers outils que tout le monde a déjà mentionné, et après avoir utilisé l'approche par dépréciations par étapes déjà mentionnée, gardez à l'esprit que vous risquez peut-être de vous retirer de l'entreprise lorsque la suppression effective a lieu. Laisser le code rester et faire en sorte que son exécution soit consignée et s’assurer que toutes les alertes concernant son exécution vous sont définitivement communiquées (ou à vos successeurs et ayants droit).
Si vous ne suivez pas cette approche, vous serez probablement tué par votre femme. Si vous conservez le code (comme chaque souvenir), vous pourrez vous reposer sur le fait que la loi de Moore vient à votre secours et que le coût de l'espace disque utilisé par le code, qui ressemble à un "rocher dans ma chaussure", réduit chaque année et vous ne risquez pas de devenir le centre de nombreux commérages de refroidisseur d’eau et de regards étranges dans les couloirs.
PS: Pour clarifier en réponse à un commentaire. La question initiale est "Comment effacez -vous en toute sécurité .." bien sûr, le contrôle de version est supposé dans ma réponse. Tout comme creuser dans la corbeille pour trouver le précieux est supposé. Aucun organisme sensé ne jette le code et le contrôle de version ne devrait faire partie de la rigueur de chaque développeur.
Le problème concerne le code qui peut être superflu. Nous ne pourrons jamais savoir qu'un morceau de code est superflu à moins de pouvoir garantir que 100% des chemins d'exécution ne l'atteignent pas. Et il est supposé que ce logiciel est suffisamment volumineux pour que cette garantie soit quasiment impossible. Et à moins que je ne lise mal la question, le seul moment où ce fil de discussion est pertinent concerne les cas de production où le code supprimé peut être appelé, ce qui pose un problème d'exécution / de production. Le contrôle de version ne sauve pas le retard de tous en raison d’échecs de production. Le commentaire sur "Contrôle de version" n’est donc pas pertinent pour la question ni pour mon argument initial, c’est-à-dire que nous vous déconseillons d’être obsolète sur une très longue période si vous en avez vraiment besoin, sinon ne le faites pas.
IMHO, le commentaire est superflu et est un candidat à la suppression.
la source
Peut - être que le compilateur ne remarque que, ça ne fait pas de chichi.
Exécutez une construction avec des optimisations complètes du compilateur, orientées vers la taille. Supprimez ensuite le code suspect et relancez la construction.
Comparez les binaires. S'ils sont identiques, le compilateur a remarqué et supprimé le code en silence. Vous pouvez le supprimer de la source en toute sécurité.
Si les fichiers binaires sont différents ... alors cela n'est pas concluant. Cela pourrait être un autre changement. Certains compilateurs incluent même la date et l'heure de compilation dans le binaire (et peut-être que cela peut être configuré à distance!)
la source
En fait, j'ai récemment rencontré cette situation exacte, avec une méthode appelée "deleteFoo". Nulle part dans la base de code entière cette chaîne n’a été trouvée autre que la déclaration de la méthode, mais j’ai sagement écrit une ligne de journal en haut de la méthode.
PHP:
Il s'avère que le code a été utilisé! Certains appels de méthode AJAX "méthode: delete, elem = Foo" sont ensuite concaténés et appelés avec call_user_func_array () .
En cas de doute, connectez-vous! Si vous avez passé suffisamment de temps sans voir le journal rempli, envisagez de supprimer le code. Mais même si vous supprimez le code, laissez le journal en place et un commentaire avec la date pour faciliter la recherche du commit dans Git pour le gars qui doit le maintenir!
la source
Utilisez
grep
ou quels que soient les outils disponibles en premier, vous pouvez trouver des références au code. (Pas à l'origine mes instructions / conseils.)Ensuite, décidez si vous souhaitez risquer de supprimer le code ou si ma suggestion pourrait éventuellement être utilisée:
Vous pouvez modifier la fonction / le bloc de code pour écrire qu'il a été utilisé dans un fichier journal. Si aucun message de ce type n'est "jamais" enregistré dans le fichier journal, vous pouvez probablement supprimer le code de journalisation.
Deux problèmes:
Obtenir le journal des autres utilisateurs. Vous pouvez peut-être définir un indicateur global qui plantera le programme à la sortie et demander à l’utilisateur de vous envoyer le journal des erreurs.
Retracer l'appelant. Dans certains langages de haut niveau (par exemple, Python), vous pouvez facilement obtenir une trace. Mais dans les langages compilés, vous devrez enregistrer l'adresse de retour dans le journal et forcer un vidage mémoire à la sortie (point 1).
En C, cela devrait être assez simple: utilisez un bloc conditionnel (par exemple, #ifdef ... #endif) pour l'utiliser uniquement lorsque vous savez que cela fonctionnera (et que vous l'avez testé) et lisez simplement l'adresse de retour. de la pile (peut nécessiter ou non un langage d'assemblage intégré).
L'enregistrement des arguments dans le fichier journal peut être utile ou non.
la source
Si vous savez ce que fait le code qui l’entoure, testez-le pour voir s’il tombe. Il s’agit du moyen le plus simple et le plus rentable de modifier le code sur lequel vous travaillez et vous devriez le faire de toute façon si vous souhaitez modifier le code sur lequel vous travaillez.
Si, par contre, vous refactorisez un morceau de code où vous ne savez pas ce qu'il fait, ne le supprimez pas . Comprenez-le d'abord, puis réfléchissez-le si vous déterminez qu'il est sûr (et seulement si vous pouvez déterminer que le refactoring serait une utilisation appropriée de votre temps).
Maintenant, il peut y avoir des circonstances (je sais que je l'ai moi-même rencontré) où le code "mort" n'est en réalité connecté à rien . Telles des bibliothèques de code développées par un fournisseur et qui n'ont jamais été implémentées nulle part, car elles sont devenues obsolètes immédiatement après la livraison de l'application (pourquoi oui, j'ai un exemple spécifique en tête, comment le saviez-vous?).
Personnellement, j’ai fini par supprimer tout le code, mais c’est un risque énorme que je ne recommande pas de prendre à la légère - en fonction de la quantité de code que ce changement pourrait avoir un impact (car il ya toujours le potentiel que vous avez oublié doit être extrêmement prudent et exécuter des tests unitaires agressifs pour déterminer si la suppression de cet ancien code héritera votre application.
Tout cela étant dit, votre temps et votre santé mentale ne valent probablement pas la peine d'essayer de supprimer du code comme celui-là. Pas à moins que cela ne devienne un problème sérieux avec votre application (par exemple, ne pas être en mesure de réaliser des analyses de sécurité en raison de la surcharge de l'application ... pourquoi oui, j'ai encore un exemple en tête), je ne le recommanderais donc pas, sauf si vous atteignez une telle situation où le code a vraiment commencé à pourrir de manière percutante.
En bref, si vous savez ce que fait le code, commencez par le tester. Si vous ne le faites pas, vous pouvez probablement le laisser seul. Si vous savez que vous ne pouvez pas en rester là, consacrez votre temps à tester le changement de manière agressive avant de le mettre en œuvre.
la source
Mon approche, que j'ai toujours supposée être la norme de l'industrie dans ce cas, n'a étrangement pas été mentionnée jusqu'à présent:
Obtenez une deuxième paire d'yeux.
Il existe différents types de "code inutilisé" et dans certains cas, la suppression est appropriée, dans d'autres cas, vous devez la reformuler, et dans d'autres cas, vous vous enfuyez aussi loin que vous le pouvez et vous ne regardez jamais en arrière. Vous devez déterminer lequel il s’agit et, pour ce faire, vous ferez le mieux avec un second - expérimenté! - développeur, quelqu'un qui connaît très bien la base de code. Cela réduit considérablement le risque d'erreur inutile et vous permet d'apporter les améliorations nécessaires pour maintenir la base de code dans un état maintenable. Et si vous ne le faites pas, à un moment donné, vous serez à court de développeurs qui connaissent très bien la base de code.
J'ai aussi vu l'approche de journalisation - pour être plus précis, j'ai vu le code de journalisation: encore plus de code mort qui a été laissé là pendant 10 ans. L'approche de journalisation est tout à fait décente si vous parlez de supprimer des fonctionnalités entières, mais pas si vous supprimez simplement un petit morceau de code mort.
la source
La réponse simple à votre question est que vous ne pouvez pas supprimer en toute sécurité un code que vous ne comprenez pas, ce qui implique de ne pas comprendre comment il est appelé. Il y aura des risques.
Vous devrez juger de la meilleure façon d’atténuer ce risque inévitable. D'autres ont mentionné l'exploitation forestière. La journalisation peut évidemment prouver qu’elle est utilisée, mais ne peut pas prouver que ce n’est pas le cas. Étant donné que le principal problème du code mort est qu'il est maintenu, vous pouvez peut-être vous en tirer en ajoutant un commentaire disant qu'il s'agit d'un code mort présumé, et ne pas effectuer de maintenance dessus.
Si le code est sous contrôle de code source, vous pouvez toujours savoir quand il a été ajouté et déterminer comment il a été appelé à ce moment-là.
En fin de compte, vous pouvez le comprendre, le laisser tranquille ou tenter votre chance.
la source
Si le développeur du code en question est toujours disponible, examinez la suppression du code avec lui . En outre, lire les commentaires dans le code .
Vous obtiendrez la bonne explication, pourquoi ce code a été ajouté et à quelle fonction sert-il. Il peut facilement s'agir d'une prise en charge pour un cas d'utilisation spécifique ou même ne pas disposer de suffisamment d'expertise pour juger si cela n'est vraiment pas nécessaire. Dans les cas extrêmes, il est possible de supprimer toutes les instructions libres d’un programme C et de ne rien remarquer de mal (cela peut prendre quelques minutes pour manquer de mémoire).
C’est vraiment une mauvaise culture que l’auteur du code se trouve à côté de vous, mais vous ne voyez aucune raison de parler parce que vous êtes sûr qu’il écrit juste du mauvais code, et le vôtre est si parfait. Et, bien sûr, il écrit simplement des mots au hasard dans les commentaires, inutile de perdre du temps à lire.
L'une des raisons les plus importantes pour écrire un commentaire dans le code est d'expliquer POURQUOI il a été implémenté de cette façon. Vous pouvez être en désaccord avec la solution, mais vous devez prendre en compte le problème.
Une discussion avec l'auteur peut également révéler que le code est le reste historique de quelque chose qui a été enlevé ou qui n'a jamais été fini. Il est donc sûr de le supprimer.
la source
Je suis tout à fait d'accord avec le premier point de Markus Lausberg: le code doit absolument être analysé à l'aide d'outils. Les cerveaux de singe ne doivent pas être confiés à ce genre de tâche!
La plupart des langages de programmation standard peuvent être utilisés dans les IDE et tous les IDE qui méritent d'être appelés ont une fonctionnalité "trouver pour tous les usages" qui est exactement le bon outil pour ce type de situation. (Ctrl + Shift + G dans Eclipse par exemple)
Bien sûr: les outils de l'analyseur statique ne sont pas parfaits. Il faut être conscient des situations plus complexes dans lesquelles la décision d'appeler la méthode en question n'est prise qu'au moment de l'exécution (appels via Reflection, appels aux fonctions "eval" dans les langages de script, etc.).
la source
Deux possibilités:
la source