J'ai appris beaucoup de codage, cependant, cela a toujours été dans un environnement scientifique (pas informatique), complètement autodidacte sans personne pour me guider dans la bonne direction. Ainsi, mon parcours de codage a été ... désordonné. J'ai remarqué maintenant que chaque fois que je construis un type de programme, à la fin, je réalise comment j'aurais pu le faire de manière beaucoup plus élégante, beaucoup plus efficace et d'une manière beaucoup plus flexible et facile à gérer à l'avenir. Dans certaines circonstances, je suis en fait retourné en arrière et j'ai reconstruit les choses à partir de zéro, mais ce n'est généralement pas faisable. Jusqu'à présent, la plupart de mes programmes étaient relativement petits, mais il semble assez difficile de réécrire complètement de gros programmes chaque fois que vous créez quelque chose.
Je me demande simplement, est-ce une expérience normale? Sinon, comment empêchez-vous que cela se produise? J'ai essayé de planifier les choses à l'avance, mais je n'arrive pas à tout prévoir avant de commencer à élaborer du code.
Ce sentiment est tout à fait normal et attendu. Cela signifie que vous apprenez. Presque chaque fois que je commence un nouveau projet, je commence dans une direction et finis par le concevoir différemment à la fin.
Il est courant de développer d'abord un prototype avant de commencer sur la vraie chose. Il est également courant de revoir l'ancien code et refactor it. C'est plus facile si votre conception est modulaire - vous pouvez facilement reconcevoir des morceaux et des pièces à la fois sans avoir à jeter totalement votre ancienne conception.
Pour certaines personnes, il est utile d'écrire pseudo-code en premier. D'autres trouvent utile de commencer par écrire commentaires décrivant ce que fera le code, puis d'écrire le code une fois que la structure générale est là. Ces deux éléments vous aideront à mieux planifier votre conception et pourraient éviter la nécessité d'une réécriture.
Si vous faites partie d'une équipe, un processus de révision est crucial pour le processus de conception. Demandez à quelqu'un d'examiner votre code afin que vous puissiez apprendre à améliorer votre conception.
C'est une expérience très courante
La plupart des gens avec qui j'interagis, et moi-même aussi, ressentent cela. D'après ce que je peux dire, c'est que vous en apprendrez plus sur le domaine et les outils que vous utilisez lorsque vous écrivez votre code, ce qui vous amène à reconnaître de nombreuses possibilités d'amélioration après avoir déjà écrit votre programme.
L'autre raison est que vous avez peut-être une idée en tête de la solution de code propre idéale, puis le monde réel et ses limites désordonnées vous gênent, vous obligeant à écrire des solutions de contournement imparfaites et des hacks qui peuvent vous laisser insatisfaits.
"Tout le monde a un plan jusqu'à ce qu'ils soient frappés au visage."
Que faire à ce sujet
Dans une certaine mesure, vous devrez apprendre à accepter que votre code ne sera jamais parfait. Une chose qui m'a aidé avec cela est l'état d'esprit de "Si je déteste le code que j'ai écrit il y a un mois, cela signifie que j'ai appris et suis devenu un meilleur programmeur".
Un moyen d'atténuer le problème consiste à être constamment à la recherche d'améliorations potentielles tout en travaillant et en continuant la refonte. Assurez-vous de trouver un bon équilibre entre la refactorisation et l'ajout de nouvelles fonctionnalités/correction de bugs. Cela n'aidera pas les gros problèmes de conception, mais cela vous laissera généralement une base de code plus raffinée dont vous pouvez être fier.
Apprenez le refactoring - l'art de s'améliorer progressivement code. Nous apprenons tous tout le temps, il est donc très courant de réaliser que le code que vous avez écrit vous-même pourrait être mieux écrit.
Mais vous devriez pouvoir transformer le code existant pour appliquer ces améliorations sans avoir à recommencer à zéro.
Si vous avez d'excellentes exigences statiques et que vous les comprenez bien et que vous avez le temps pour une analyse détaillée, vous avez une chance de trouver un bon design qui vous plaira quand vous aurez terminé.
Même dans ce cas heureux, vous pouvez apprendre de nouvelles fonctionnalités de langage qui auraient aidé à améliorer la conception.
Cependant, généralement, vous ne serez pas aussi chanceux: les exigences seront moins que stellaires et incomplètes et bien que vous pensiez les avoir comprises, il s'avère qu'il y a des domaines sur lesquels vous avez fait des hypothèses invalides.
Ensuite, les exigences changeront à mesure que les utilisateurs auront un aperçu de vos livrables initiaux. Ensuite, quelque chose que les utilisateurs ne contrôlent pas changera par exemple droit fiscal.
Tout ce que vous pouvez faire, c'est concevoir, en supposant que les choses vont changer. Refactorisez quand vous le pouvez, mais réalisez que le temps et le budget signifieront souvent que votre livrable final n'est pas aussi élégant qu'il l'aurait été si vous saviez au début ce que vous savez maintenant.
Au fil du temps, vous pourrez mieux analyser les exigences que vous recevez et obtenir un nez pour lequel les parties de votre conception auront probablement besoin de flexibilité pour absorber le changement.
En fin de compte cependant, acceptez que le changement est constant et ignorez le pincement qui dit "J'aurais pu mieux faire". Soyez fier et heureux d'avoir fourni une solution.
Comment puis-je éviter de me sentir toujours comme si je reconstruisais complètement mon programme à partir de zéro, je le ferais beaucoup mieux?
Ce que vous pourriez faire, c'est de créer un prototype jetable, avant de commencer à faire le "vrai" projet. Rapide et sale. Ensuite, lorsque vous obtenez un prototype pour prouver un concept, vous apprenez à connaître le système et à faire les choses correctement.
Mais ne soyez pas surpris, si après N années vous revenez à ce code, et pensez "quel bordel".
Rappelez-vous ce mantra:
La solution parfaite n'est pas toujours la solution idéale . La solution idéale est celle qui atteint le statut "assez bon" avec le moins de travail.
Si vous répondez oui à toutes ces questions, alors votre logiciel est "assez bon" et il n'y a aucune bonne raison de le réécrire à partir de zéro. Appliquez plutôt les leçons de conception que vous avez apprises à votre prochain projet.
Il est parfaitement normal que chaque programmeur ait quelques programmes en désordre dans son passé. Il m'est arrivé plusieurs fois au cours de ma carrière de développeur de logiciels que j'ai regardé du code, je me suis demandé "Quel idiot a écrit ce gâchis?", J'ai vérifié l'historique des versions et j'ai remarqué que c'était moi d'il y a plusieurs années.
J'ai essayé de planifier les choses à l'avance, mais je n'arrive pas à tout prévoir avant de commencer à élaborer du code.
Il est tentant de penser qu'une planification parfaite vous donnera une conception/architecture de logiciel parfaite, cependant, il s'avère que c'est catégoriquement faux. Il y a deux gros problèmes avec cela . Premièrement, "sur papier" et "le code" correspondent rarement, et la raison en est qu'il est facile de - dire comment cela devrait être fait par opposition à en fait le faire. Deuxièmement, des changements imprévus dans les exigences se manifestent à la fin du processus de développement, ce qui n'aurait pas pu être motivé dès le départ.
Avez-vous entendu parler du mouvement Agile? C'est une façon de penser où nous valorisons "réagir au changement" par opposition à "suivre un plan" (entre autres des choses). Voici le manifeste (c'est une lecture rapide). Vous pouvez également en savoir plus sur Big Design Up Front (BDUF) et quels sont les pièges.
Malheureusement, la version d'entreprise de "Agile" est un tas de faux (maîtres Scrum certifiés, processus lourd au nom de "Agile", forçant Scrum, forçant une couverture de code à 100%, etc.), et entraîne généralement des changements de processus insinus parce que les gestionnaires pense que l'Agile est un processus et une solution miracle (dont ce n'est ni l'un ni l'autre). Lisez le manifeste agile, écoutez les gens qui a commencé ce mouvement comme Oncle Bob et Martin Fowler, et ne vous laissez pas entraîner dans la version absurde de "corporate Agile".
En particulier, vous pouvez généralement vous contenter de simplement faire TDD (Test Driven Development) sur du code scientifique , et il y a de fortes chances que votre projet logiciel se révèle sacrément bien. C'est parce que le code scientifique qui réussit a principalement des interfaces ultra-utilisables, avec des performances comme préoccupation secondaire (et parfois concurrente), et donc vous pouvez vous en sortir avec une conception plus "gourmande". TDD oblige en quelque sorte votre logiciel à être ultra-utilisable , parce que vous écrivez comment vous voulez les choses à appeler ( idéalement) avant de les mettre en œuvre. Il force également les petites fonctions avec les petites interfaces qui peuvent être rapidement appelées d'une manière simple, "entrée"/"sortie", et cela vous met en bonne position pour refactoriser en cas de changement des exigences.
Je pense que nous pouvons tous convenir que numpy
est un logiciel informatique scientifique performant. Leurs interfaces sont petites, super utilisables et tout se joue bien ensemble. Notez que le guide de référence de numpy
recommande explicitement TDD: https://docs.scipy.org/doc/numpy- 1.15.1/reference/testing.html . J'ai utilisé TDD dans le passé pour le logiciel d'imagerie SAR (Synthetic Aperature Radar): et je peux également affirmer qu'il fonctionne extrêmement bien pour ce domaine particulier.
Avertissement: La partie conception de TDD fonctionne moins bien dans les systèmes où une refactorisation fondamentale (comme décider que vous avez besoin que votre logiciel soit hautement simultané) serait difficile , comme dans un système distribué. Par exemple, si vous deviez concevoir quelque chose comme Facebook où vous avez des millions d'utilisateurs simultanés, faire TDD (pour piloter votre conception) serait une erreur (vous pouvez toujours utiliser après vous avez un = préliminaire conception, et faites simplement "tester le premier développement"). Il est important de penser aux ressources et à la structure de votre application avant sauter dans le code. TDD ne vous mènera jamais vers un système distribué hautement disponible.
Comment puis-je éviter de me sentir toujours comme si je reconstruisais complètement mon programme à partir de zéro, je le ferais beaucoup mieux?
Compte tenu de ce qui précède, il devrait être quelque peu évident qu'un design parfait est en fait impossible à réaliser, donc la poursuite d'un design parfait est un jeu de dupes. Vous pouvez vraiment approchez-vous seulement. Même si vous pensez vous pouvez repenser à partir de zéro, il y a probablement encore des exigences cachées qui ne se sont pas montrées. De plus, les réécritures prennent au moins aussi longtemps qu'il a fallu pour développer le code original. Il ne sera certainement pas plus court, car il est probable que la conception nouveau aura ses propres problèmes imprévus, et vous devrez réimplémenter toutes les fonctionnalités de l'ancien système.
Une autre chose à considérer est que votre conception n'a d'importance que lorsque les exigences changent. Peu importe la gravité de la la conception est si rien ne change jamais (en supposant qu'il soit entièrement fonctionnel pour les cas d'utilisation actuels). J'ai travaillé sur une ligne de base qui avait une instruction de commutation de 22 000 lignes (la fonction était encore plus longue). Était-ce une conception terrible? Zut oui, c'était horrible. L'avons-nous réparé? Non, cela a très bien fonctionné, et cette partie du système n'a jamais vraiment causé de plantages ou de bugs. Il n'a été touché qu'une seule fois au cours des deux années où j'ai participé au projet, et quelqu'un, vous l'aurez deviné, a inséré un autre boîtier dans l'interrupteur. Mais cela ne vaut pas la peine de prendre le temps de réparer quelque chose qui est touché si rarement, ce n'est tout simplement pas. Que la conception imparfaite soit telle qu'elle est, et si elle n'est pas cassée (ou constamment cassée), ne la réparez pas. Alors peut-être que vous pourriez faire mieux ... mais cela vaudrait-il la peine d'être réécrit? Que gagnerez-vous?
HTH.
Je suis entièrement d'accord avec la réponse fournie par Andreas Kammerloher, mais je suis surpris que personne n'ait encore suggéré d'apprendre et d'appliquer certaines des meilleures pratiques de codage. Bien sûr, ce n'est pas une solution miracle, mais en utilisant une approche ouverte, des modèles de conception, en comprenant quand votre code sent, etc., vous ferez un meilleur programmeur. Examinez quelle est la meilleure utilisation des bibliothèques, des cadres, etc. Il y a bien plus encore, je ne fais que gratter la surface.
Cela ne signifie pas que vous ne considérerez pas votre ancien code comme un déchet total (vous verrez en fait les programmes les plus anciens encore plus de déchets que vous sans cette connaissance) mais avec chaque nouveau logiciel que vous écrivez, vous verrez vous vous améliorez. Notez également que le nombre de meilleures pratiques de codage augmente avec le temps, certaines changent simplement pour que vous n'atteigniez jamais la perfection. Acceptez ceci ou tout à fait le chemin.
Une autre bonne chose est d'avoir une révision de code. Lorsque vous travaillez seul, il est facile de couper les coins ronds. Si une deuxième personne examine votre code, elle pourra vous indiquer où vous ne respectez pas ces meilleures pratiques. De cette façon, vous produirez un meilleur code et vous apprendrez quelque chose.
Pour ajouter aux autres excellentes réponses ici, une chose que je trouve utile est savoir où vous voulez vous rendre.
Il est rare d'avoir le feu vert pour une refonte importante de son propre chef. Mais vous pouvez souvent refaire de plus petits morceaux au fur et à mesure, "sous le radar", lorsque vous travaillez sur chaque zone de la base de code. Et si vous avez un objectif en tête, vous pouvez saisir ces opportunités pour vous déplacer, pas à pas, dans la bonne direction.
Cela peut prendre du temps, mais la plupart des étapes amélioreront le code et le résultat final en vaudra la peine.
Aussi, se sentir comme si vous pouviez faire mieux est un bon signe ! Cela montre que vous vous souciez de la qualité de votre travail et que vous l'évaluez de manière critique; vous apprenez et vous améliorez probablement. Ne laissez pas ces choses vous inquiéter - mais n'arrêtez pas de les faire!
Vous êtes tombé par inadvertance sur l'un des plus grands défis de l'humanité (aventures), le pont entre l'homme et la machine. Le pont entre l'homme et la structure physique, le génie civil par exemple, est en cours depuis environ 200 ans ou plus.
Étant donné que le développement de logiciels n'est vraiment devenu courant que dans les années 90, il a environ 30 ans. Nous avons appris qu’il ne s’agit pas tant d’une discipline d’ingénierie que de sciences sociales, et nous venons à peine de commencer.
Oui, vous allez essayer TDD, Refactoring, Programmation fonctionnelle, le modèle de référentiel, Event Sourcing, quelque chose de MV, Java Script (<- Faites cela, c'est fou), Model Binding, No Sql, Containers , Agile, SQL (<- faites-le, c'est puissant).
Il n'y a pas de solution unique. Même les experts saisissent toujours les pailles.
Bienvenue et soyez prévenu, c'est un endroit solitaire; mais absolument fascinant.
Je vais aller un peu à contre-courant. C'est incroyablement commun , mais ce n'est pas acceptable . Cela indique que vous ne reconnaissez pas de bonnes façons d'organiser votre code lorsque vous l'écrivez. Le sentiment vient de votre code pas simple.
Votre expérience était aussi la mienne depuis longtemps, mais récemment (ces deux dernières années), j'ai produit plus de code qui ne me rend pas je sens que je dois tout jeter. Voici à peu près ce que j'ai fait:
Mon code est désormais plus "procédural", ce qui signifie qu'il est organisé en quelles actions il prend plutôt que quelles structures de données il utilise. J'utilise des objets dans des langages où les fonctions autonomes ne peuvent pas être remplacées à la volée (C # et Java ne peut pas remplacer les fonctions à la volée, Python peut)). J'ai tendance à créer plus de fonctions utilitaires maintenant, qui ne font que mettre un peu de passe-partout ennuyeux pour que je puisse réellement lire la logique de mon code. (Par exemple, lorsque je devais traiter toutes les combinaisons d'éléments dans une liste, j'ai déplacé l'index en boucle vers une méthode d'extension qui renvoie Tuple
s afin que la fonction d'origine ne soit pas encombrée avec ces détails d'implémentation. ) Je passe maintenant beaucoup plus de choses en tant que paramètres aux fonctions, au lieu d'avoir une fonction qui tend la main vers un autre objet pour le récupérer. (L'appelant le récupère ou le crée à la place et le transmet.) Je laisse maintenant plus de commentaires qui expliquent les choses que ne sont pas évidents simplement en regardant le code , ce qui facilite le suivi de la logique d'une méthode. Je n'écris des tests que dans des cas limités où je ' suis préoccupé par la logique de quelque chose que je viens de faire, et j'évite d'utiliser des simulacres. (Je fais plus de tests d'entrée/sortie sur des éléments logiques isolés.) Le résultat est un code qui n'est pas parfait , mais qui semble en fait d'accord , même 2 ou 3 ans plus tard. C'est du code qui réagit assez bien au changement; des choses mineures peuvent être ajoutées ou supprimées ou modifiées sans que le système entier ne s'effondre.
Dans une certaine mesure, vous devez traverser une période où les choses sont un gâchis pour que vous ayez une certaine expérience. Mais si les choses sont toujours si désordonnées que vous voulez tout jeter et recommencer, quelque chose ne va pas; tu n'apprends pas.
En vous rappelant que votre temps est limité. Et votre temps futur est également limité. Que ce soit pour le travail, l'école ou des projets personnels, en ce qui concerne le code working, vous devez vous demander "est-ce que la réécriture est la meilleure utilisation de mon temps limité et précieux?". Ou peut-être, "est-ce l'utilisation la plus responsable de mon temps limité"?
Parfois, la réponse sera sans équivoque oui. Habituellement non. Parfois, ce sera sur la clôture, et vous devrez utiliser votre discrétion. Parfois, c'est une bonne utilisation de votre temps simplement à cause des choses que vous apprendrez en le faisant.
J'ai beaucoup de projets, à la fois professionnels et personnels, qui bénéficieraient d'un portage/réécriture. J'ai aussi autre chose à faire.
C'est une partie tout à fait normale de l'apprentissage. Vous réalisez des erreurs au fur et à mesure.
C'est ainsi que vous vous améliorez et ce n'est pas quelque chose que vous devriez éviter.
Vous pouvez vous donner l'expérience de savoir que l'envie séduisante de réécrire est généralement improductive. Trouvez un vieux projet open source velu et inélégant de complexité modérée. Essayez de le réécrire à partir de zéro et voyez comment vous faites.
Finalement, votre instinct passera de penser "je pourrais réécrire ce système tellement mieux" à penser "la cruauté de ce système peut être le signe d'une complexité qui n'est pas immédiatement apparente."