web-dev-qa-db-fra.com

Travailler sur le code de quelqu'un d'autre

J'ai à peine un an d'expérience en codage. Après avoir commencé à travailler, la plupart du temps, je travaillais sur le code de quelqu'un d'autre, soit en ajoutant de nouvelles fonctionnalités par rapport à celles existantes, soit en modifiant les fonctionnalités existantes. Le gars qui a écrit le code actuel ne travaille plus dans mon entreprise. J'ai du mal à comprendre son code et à faire mes tâches. Chaque fois que j'ai essayé de modifier le code, j'ai en quelque sorte dérangé les fonctionnalités de travail. Que dois-je garder à l'esprit tout en travaillant sur le code de quelqu'un d'autre?

60
Xavi Valero

Le code a-t-il des tests unitaires? Sinon, je fortement vous suggère de commencer à les ajouter. De cette façon, vous pouvez écrire de nouvelles fonctionnalités/corrections de bogues en tant qu'échecs de tests, puis modifier le code que le test réussit. Plus vous en construirez, plus vous aurez confiance que votre code ajouté n'a pas cassé autre chose.

Écrire des tests unitaires pour du code que vous ne comprenez pas complètement vous aidera à comprendre ce code. Bien sûr, des tests fonctionnels doivent être ajoutés s'ils n'existent pas déjà. Mon impression était que celles-ci existaient déjà sous la question du PO. Si je me trompe sur ce point, ces tests fonctionnels devraient être votre première étape.

Eagle76dk fait un grand point pour obtenir votre manager à bord pour faire ce travail - plus de détails dans le post d'Eagle76dk.

De plus, au fur et à mesure que vous écrivez ces tests, je vous encourage à essayer d'écrire les tests afin qu'ils vérifient le comportement métier que la méthode a pu essayer d'accomplir, pas le comportement du code. En outre, ne présumez pas du tout que les comportements commerciaux que vous voyez dans le code sont les bons - si vous avez quelqu'un qui pourrait vous dire ce que l'application devrait faire, cela est dans bien des cas plus précieux que ce que le code pourrait vous dire.

En plus d'une autre réponse qui mentionnait les tests unitaires, je vous suggère de vous assurer que tout est en contrôle de version afin que vous puissiez annuler vos modifications facilement. Et faire de petites modifications pour rendre le code plus maintenable.

46
Klee

À mon avis, le moyen le plus rapide d'apprendre le code de quelqu'un d'autre (en particulier lorsque des changements déclenchent un comportement inattendu comme vous le décrivez) est de parcourir le code à l'aide d'un débogueur.

Commencez par parcourir ce qui semble être la boucle principale/méthodes principales du programme. Utilisez les fonctions pas à pas et pas à pas pour voir ce que font les différentes méthodes. Cela vous apprendra la structure générale du code.

Après cela, divisez et conquérez en progressant et en apprenant les différentes parties du programme à un niveau plus profond. Dans la plupart des débogueurs, vous pouvez étudier les variables et leurs valeurs actuelles. Étudiez comment ils changent et quand.

Définissez points d'arrêt sur les méthodes qui déclenchent les comportements qui vous concernent. Par exemple, si vous essayez de modifier un texte dans le programme et que le texte revient toujours à sa valeur d'origine, définissez des points d'arrêt à tous les endroits où le texte est modifié ou essayez de déplacer toutes ces modifications vers une seule méthode. Utilisez la pile d'appels pour voir d'où cette méthode est appelée, etc., etc.

Si la modification d'une ligne de code provoque changements inattendus à d'autres endroits, placez un point d'arrêt sur cette ligne et voyez ce qui s'y passe, par exemple en vérifiant les valeurs des variables actuelles dans la portée, en utilisant step into ou la pile d'appels pour voir d'où vient l'appel.

En faisant cela beaucoup, vous commencerez à apprendre la structure du code étonnamment rapidement. J'ai commencé comme vous l'avez fait lors de mes premiers travaux de programmation, avec beaucoup de code qui avait été écrit il y a plusieurs années et qui avait été modifié par de nombreuses personnes au fil des années. Le code n'était pas le mien seulement depuis qu'il y avait d'autres personnes qui y travaillaient en même temps. Je ne pouvais pas tout réécrire à ce stade. Écrire des tests pour tout ce code m'aurait pris des mois ou des années. Le débogueur m'a vraiment sauvé, je ne sais pas comment j'aurais appris le code sans lui ...

32
jake_hetfield

La première chose à garder à l'esprit est que l'on passe plus de temps à lire du code qu'à écrire du code. Passez du temps à comprendre comment l'autre gars a travaillé - son style et son approche des problèmes.

Essayez d'adopter le style existant autant que possible - sinon le gars après vous aura deux fois plus de réglages à faire.

Traiter avec le code de quelqu'un d'autre est la norme, pas l'exception, vous devez devenir habile à comprendre comment l'autre gars aurait résolu un problème ou implémenté une fonctionnalité. Une fois que vous avez fait cela, vous trouverez plus facile de gérer son code.

30
jmoreno

Ne soyez pas trop rapide pour supposer que le code de l'autre gars pue.

Mais soyez toujours méfiant.

Mais oui, il faut du temps pour comprendre le code d'un autre développeur. Plus une fonction ou un objet est utilisé par plusieurs parties du système, plus vous devez être prudent. Si vous pouvez résoudre le problème plus près du symptôme, cela peut parfois être utile. Par exemple, normalisez les données entrantes d'un autre objet du côté de l'objet problème de la clôture après la livraison des données, mais avant toute autre chose.

C'est un mauvais signe quand changer une chose en casse une autre de façon inattendue. Si vous avez d'autres développeurs plus expérimentés sur lesquels vous pouvez compter pour obtenir de l'aide, je vous recommande de leur demander de regarder les choses qui vous posent des problèmes. À tout le moins, vous pouvez ramasser quelques éléments en les regardant déboguer.

21
Erik Reppen

Dans un monde idéal, tout le code écrit par un développeur donné sera bien documenté, bien structuré et testé de manière compréhensible, à la fois avec des outils automatiques tels que des tests unitaires et des scripts de cas d'utilisation qu'un utilisateur parcourt pour vérifier que vous obtenez le résultat attendu.

Cependant, la première chose que vous apprendrez, c'est que nous ne vivons pas dans un monde idéal!

De nombreux développeurs ne documentent pas leur code correctement, voire mélangent la logique métier avec du code non lié, et le seul test qu'ils font est de parcourir rapidement ce qu'ils s'attendent à être le cas d'utilisation normal.

Lorsque vous travaillez avec un code comme celui-ci, la première chose que vous devez faire est d'établir ce qu'il est censé faire. S'il y a des commentaires, ils peuvent vous donner des indices, mais ne comptez pas dessus. D'après mon expérience, de nombreux codeurs ne sont pas bons pour s'expliquer et même s'ils laissent des commentaires, ils pourraient être dénués de sens. Cependant, à moins que vous ne soyez le seul codeur de l'entreprise, quelqu'un doit sûrement avoir au moins une idée de base de la raison d'être du code et de ce qu'il est censé faire. Demande autour de toi!

Si vous avez des tests unitaires, ils vous faciliteront grandement la vie. Si vous ne le faites pas, une partie de l'apprentissage de la base de code peut impliquer l'écriture de tests unitaires pour le code qui existe déjà. Normalement, cela n'est pas considéré comme une bonne pratique, car si vous écrivez des tests unitaires pour s'adapter au code existant, vous vous retrouverez avec des tests unitaires qui pensent que le code fonctionne tel quel (ils seront écrits pour supposer que le comportement qui est en fait un bogue est correct), mais au moins cela vous donne une référence. Si vous découvrez plus tard qu'un comportement que vous pensiez correct est en fait incorrect, vous pouvez modifier le test unitaire pour tester le résultat attendu plutôt que le résultat que le code donne maintenant. Une fois que vous avez effectué un test unitaire, vous pouvez apporter des modifications et évaluer les effets secondaires de vos modifications.

Enfin, la meilleure ressource dont vous disposez pour traiter un morceau de code non documenté est de demander aux utilisateurs finaux. Ils ne savent peut-être rien du code, mais ils savent ce qu'ils veulent que l'application fasse. La collecte des exigences est la première étape de tout projet, et parler avec les utilisateurs potentiels du système à développer en est toujours une partie importante. Pensez-y simplement comme faisant l'étape de capture des exigences pour un nouveau projet qui se trouve déjà avoir été construit.

Gardez à l'esprit que même un code bien écrit et bien documenté peut être difficile à comprendre pour un étranger. Le code est essentiellement une expression de la façon dont la personne qui l'a écrit pensait à l'époque, et chacun a son propre processus de pensée. Vous devrez apprendre à être un peu patient et à être détective. Il est difficile d'entrer dans le processus de réflexion d'une autre personne, mais c'est une compétence essentielle pour un programmeur qui effectue la maintenance du code existant. Comme la plupart du codage (environ 70%) est lié au maintien du code existant, c'est une compétence importante à apprendre.

Oh, et maintenant que vous avez vu la douleur que peut causer du code mal documenté, non testé et brouillé, vous ne le ferez pas au prochain pauvre développeur, non? :) Apprenez des erreurs de votre prédécesseur, commentez bien votre code, assurez-vous que chaque module a une responsabilité clairement définie à laquelle il adhère et assurez-vous d'avoir un ensemble complet de tests unitaires que vous écrivez en premier (pour les méthodologies TDD) ou au moins parallèlement au code en cours d'élaboration.

14
GordonM

Gardez à l'esprit que la capacité de lire du code que vous n'avez pas écrit est une compétence très précieuse, probablement plus précieuse que d'écrire du code. Malheureusement, cela est largement sous-estimé et sous-enseigné dans les écoles.

Ce que j'essaie de dire, c'est qu'il est normal que vous ne compreniez pas toujours le code lors de sa première lecture (tout comme il est normal que vous n'écriviez pas du code parfait la première fois). Si vous acceptez qu'il faut du temps pour obtenir un code étranger, cela ne vous dérangera pas de faire l'effort supplémentaire. Un petit résumé:

  • Les tests unitaires seraient idéaux, mais pas toujours réalistes; surtout si vous travaillez dans une grande organisation avec une lourde bureaucratie.

  • Apprenez à utiliser votre système de contrôle de version correctement; vous ne casserez jamais l'existant (pas vraiment jamais , mais c'est un bon filet de sécurité).

  • Ne présumez pas que c'est mauvais simplement parce que vous ne le comprenez pas instantanément. Ne présumez pas que c'est bon simplement parce que cela fonctionne. L'important est que vous compreniez le style de code du responsable précédent et que vous adaptiez vos lignes ajoutées à son style. Le responsable venant après vous vous en remerciera.

  • Dans certaines entreprises, malheureusement, la difficulté de lire le code peut être sous-estimée. Cela est courant dans les grandes entreprises avec des processus rigides. Ils préfèrent souvent (implicitement) votre code Push qui fonctionne rapidement plutôt que de prendre votre temps pour écrire quelque chose de propre. Je vous laisse le soin de décider de la position de votre équipe sur ce point.

  • Enfin, n'oubliez jamais que la lecture de code est une compétence. Plus vous le faites, mieux vous y arriverez. Une autre façon de le dire est que la seule façon de se perfectionner est de la pratiquer plusieurs fois. Comme mentionné ci-dessus, la lecture de code est et sera une partie beaucoup plus importante de votre travail que l'écriture.

13
rahmu

À en juger par vos problèmes de rupture par inadvertance, je vais supposer que le code n'est pas couvert par des tests automatisés. L'étape # 0 serait de commander immédiatement et de lire Travailler efficacement avec le code hérité par Michael Feathers. C'est tout simplement inestimable.

Les étapes de base que je suggérerais:

  • Couvrez le code avec des tests couvrant la fonctionnalité actuelle.
  • Refactor jusqu'à compréhensible.
  • Rédigez un test pour la fonctionnalité nouvelle ou modifiée.
  • Implémentez la nouvelle fonctionnalité.
  • Refactoriser jusqu'à satisfaction.

Je laisse délibérément de côté la spécification de la saveur des tests (unité, intégration, ...) - obtenez simplement une sorte de couverture de test automatisée.

(et, oui, suivez le style de codage en termes de mise en page et de dénomination)

11
rjnilsson

Comme mentionné précédemment: bienvenue dans le monde réel. Je ne peux qu'être d'accord avec les réponses précédentes. Je souhaite seulement étendre la réponse avec mon expérience de travail sur les estimations de temps.

Une bonne suggestion pour que votre patron soit clair, il faudra du temps pour apprendre comment les autres développeurs pensent. Habituellement, vous constaterez que la solution actuelle dépend souvent de l'âge et de l'expérience du développeur.

Si vous avez de la chance, la tâche à accomplir doit être analysée et la compréhension de la documentation vous aidera beaucoup (mais ce n'est souvent pas le cas).

D'après mon expérience, lorsque vous modifiez d'autres codes, essayez de ne pas modifier le code qui n'implique pas votre tâche actuelle. Vous connaissez peut-être une meilleure solution ou elle pourrait être écrite de manière plus intuitive, mais sa modification entraîne souvent des problèmes tels que:

  • La tâche prendra plus de temps et votre patron ne la comprendra pas.
  • Le code que vous modifiez doit être testé et cela coûte cher. La solution actuelle a été testée et approuvée.
  • Il sera difficile de voir quels changements résolvent la tâche en cours et quelles sont les corrections "justes".

Mais n'hésitez pas à en parler à votre patron, si vous voyez quelque chose que vous pensez être différent (cela montre simplement que vous pouvez penser).

Enfin, assurez-vous d'avoir suffisamment de temps pour trouver la solution. Une solution plus rapide vient avec l'expérience. Mais il y a rarement une solution rapide, car c'est la première/principale raison des erreurs et du code non maintenable.

10
Eagle76dk

Pensez-y comme effectuer une opération sur une personne.

Vous recherchez à l'intérieur le problème que vous devez résoudre et vous remarquez que la plupart des artères, etc. ne sont pas configurées comme vous le feriez - alors vous les coupez et les hachez jusqu'à ce qu'il vous semble correct, puis corrigez le problème.

Étonnamment, votre patient décède presque immédiatement.

Les applications héritées sont les mêmes. Ils ont déjà une façon de travailler - vous devez comprendre les différents composants du logiciel et comment ils sont liés les uns aux autres, puis effectuer vos modifications pour que cela fonctionne de la même manière. Ce n'est pas excitant de laisser libre cours à votre créativité, mais vous pouvez le faire sur des projets personnels.

Je demanderais à un ingénieur principal de s'asseoir avec vous pendant environ une heure tous les lundis et d'expliquer un aspect différent du système. Prenez des notes de ce qu'il dit et envoyez-les par courrier électronique à lui et à votre responsable pour voir si votre responsable a quelque chose à ajouter. Vous devriez vous mettre au courant assez rapidement de cette façon.

Quant à savoir comment ne pas casser les choses, assurez-vous d'abord de comprendre ce que fait le système. Testez avant - faites votre changement - testez après. Il n'y a pas de formules magiques; à mesure que vous gagnez de l'expérience, vous vous améliorez - ou vous faites renvoyer, je suppose!

5
Stefan

Une chose que je n'ai pas vraiment vue abordée ici - ne fonctionne pas sur une île.

À moins que vous ne soyez le seul programmeur de votre tenue, il y a forcément quelqu'un qui a plus d'expérience que vous, et très probablement beaucoup de gens que vous pouvez vous appuyer sur.

Poser des questions. Beaucoup d'entre eux.

Ne vous inquiétez pas de "gêner" quelqu'un d'autre (dans des limites raisonnables) - je préférerais que quelqu'un m'interrompe pour une question ou deux pendant un cycle de développement normal, plutôt que d'avoir à éteindre un incendie dans un environnement de production plus tard.

Lorsque vous êtes prêt à enregistrer quelque chose, passez-le en revue avec votre ou vos mentors. Ils devraient pouvoir vous dire non seulement si quelque chose cassera autre chose, mais surtout, pourquoi. La révision du code fera également du mentor un meilleur programmeur, lui donnant une vue du système qu'il ne verrait pas autrement aussi souvent.

N'oubliez pas - vous apprenez non seulement le système comme tout nouvel employé devrait le faire, mais vous apprenez également à devenir programmeur.

Et cinq ans plus tard, encouragez le prochain New Guy à vous utiliser comme mentor.

3
Wonko the Sane

Quand il s'agit de déboguer du code, n'oubliez pas: il y a toujours une raison. Lorsque vous essayez de trouver et de corriger le même bug stupide depuis quelques jours et que vous ne progressez pas, il est tentant de penser à un ou plusieurs des éléments suivants:

  • Je ne suis tout simplement pas assez intelligent pour comprendre comment ce code fonctionne

  • Le gars qui a écrit ce code n'avait aucune idée de ce qu'il faisait

  • La magie est impliquée: la magie très noire

Ce sont toutes des formes d'abandon. L'antidote est de toujours se souvenir que les ordinateurs sont déterministes: il y a toujours une raison pour ce qu'ils font. Le code peut sentir la marée basse dans une conserverie de poisson et ressembler à un bol géant de linguine, mais en étant rationnellement implacable et en gardant l'esprit ouvert, vous le comprendrez.

2
Caleb

Que vous écriviez des tests unitaires lorsque cela est possible ou que vous écriviez de petites applications impliquant le code que vous modifiez, vous devrez regarder, comprendre, puis documenter la logique.

Si le code fonctionne principalement - sonne comme ça - alors je conserverais le style de la mise en forme du code pour ce module, que ce soit votre style ou non. Il garde les choses uniformes. Cependant, les bons commentaires ne se démodent jamais.

Je conseille un système de test et une plateforme de test, où vous pouvez modifier et tester ce code, sans interrompre la production.

Si vous pouvez supprimer des éléments du code dans une bibliothèque, je le ferais, sauf si vous travaillez sur une bibliothèque.

Au fil du temps, une fois que vous avez compris la logique, vous pouvez réécrire et tester.

Ces conseils dépendent de la langue que vous utilisez, de la possibilité d'obtenir un banc d'essai et d'autres contraintes que vous avez.

1
octopusgrabbus

Essayez d'utiliser des outils d'analyseur de code pour trouver le code inutilisé qui peut être supprimé - donc au moins vous n'avez pas à vous soucier de ce code.

1
FrVaBe

Il a été remarqué ci-dessus que vous devez comprendre le but du système, pas seulement les détails du code. Un programmeur possédant suffisamment d'expérience pour rédiger un système de saisie de commandes est généralement à l'aise avec la partie "aller de l'avant", qui implique la sélection de produits, le formatage d'une facture et le traitement du paiement. Là où ils se retrouvent bloqués, c'est lorsque l'utilisateur décide de ne rien faire et commence à annuler les transactions, ou lorsqu'il fait une erreur dans le traitement des paiements et appuie sur le bouton "Retour". À ce stade, de nombreux programmeurs sont déconcertés, car ils voient le code "apparaître de nulle part" et ne peuvent pas comprendre pourquoi il est là.

En bref, vous devez comprendre non seulement le "flux normal", mais tous les retours en arrière nécessaires si quelqu'un fait une erreur ou change d'avis. Cela devient encore pire avec les remplacements de superviseur, où certains codes ne peuvent être exécutés qu'avec certains privilèges de compte.

Si quelqu'un écrit 10 000 lignes de code par an et qu'une application a une "durée de vie" de 10 ans, un programmeur chargé de récupérer le travail de quelqu'un d'autre devra peut-être comprendre 100 000 lignes de code. Divisez ceci par 50 lignes par page soit 2000 pages. Si le programme est écrit sur un modèle de conception, le programmeur constatera que la compréhension d'un "bloc" conduit à au moins une compréhension générale de la plupart des autres. Sinon, il est nécessaire de lire chaque dernière ligne.

Certains programmeurs "font juste ce qu'on leur dit" et écrivent des spaghettis. Ils ne comprennent jamais la "vue d'ensemble" - ils mettent simplement des correctifs lorsque les utilisateurs se plaignent. Dans une telle circonstance, c'est une bonne idée de commencer à migrer tout ce que vous pouvez vers un modèle approprié. Finalement, cela peut signifier recoder des choses qui ne sont pas "cassées". Ne vous inquiétez pas, assurez-vous que tant que c'est votre projet, il sera progressivement plus facile à maintenir.

1
Meredith Poor

Il y a des réponses vraiment sympas ici. Mais je pense qu'il vaut peut-être aussi la peine de mentionner à quel point la familiarité avec de bons modèles de conception peut aider, lire du code existant (bien écrit) et écrire du code lisible.

Bien sûr, cela peut être très déroutant lorsque vous rencontrez un SomethingFactory dans le code existant, qui ne suit pas réellement le modèle d'usine . Mais autant que votre équipe et votre cadre le permettent, il peut être avantageux de limiter ces cas au minimum.

Suivre les modèles de conception (là où les besoins de l'entreprise le permettent) peut également réduire considérablement la duplication de code, ce qui réduit à son tour les bogues lors des modifications futures.

Quelques bonnes sources sur les modèles de conception sont

http://sourcemaking.com/design_patterns

http://www.oodesign.com/

et bien sûr le livre

http://www.Amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612

0
Nameless One

Le suivi du flux de contrôle entre les méthodes est très important pour développer une carte mentale de la logique métier.

Notre solution est basée sur la reconnaissance que l'une des rares informations fiables disponibles à l'approche d'un système hérité est le système en cours d'exécution. Notre approche réifie les traces d'exécution et utilise la programmation logique pour exprimer des tests sur celles-ci.

La génération d'un modèle de données de workflow est la meilleure façon d'analyser tous les chemins de code:

En pratique, la révision du code devient difficile à gérer dans les flux de travail scientifiques hérités. L'origine de ces flux de travail signifie que les pratiques d'ingénierie logicielle peuvent ne pas avoir été appliquées pendant le développement, ce qui conduit à une base de code qui est effectivement masquée. Bien que l'analyse statique possède des techniques bien développées pour l'analyse des flux de données, elles ne prennent pas en charge le comportement dans les workflows du monde réel. Par exemple, lorsqu'un fichier de configuration doit être chargé pour déterminer comment les données doivent être traitées, ou lorsque l'évaluation de code dynamique est utilisée.

Et la visualisation du workflow est idéale:

Un motif commun, se prêtant au développement visuel, est la présentation d'un flux de travail sous forme de graphique. Cela protège l'utilisateur de la complexité sous-jacente des ressources et de l'exécution

Références

0
Paul Sweatte