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, mais il s'avère que c'est absolument faux. Cela pose deux gros problèmes. Premièrement, "sur le papier" et "le code" correspondent rarement, et la raison en est qu'il est facile de dire comment procéder, plutôt que de le faire . Deuxièmement, des changements imprévus dans les exigences deviennent apparents à un stade avancé du processus de développement et n’auraient pas pu être raisonnés dès le départ.
Avez-vous entendu parler du mouvement Agile? C'est une façon de penser où nous valorisons la "réaction au changement" par opposition au "suivi d'un plan" (entre autres). Voici le manifeste (c'est une lecture rapide). Vous pouvez également en savoir plus sur Big Design Up Front (BDUF) et sur les pièges à éviter.
Malheureusement, la version d'entreprise de "Agile" est un groupe 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 aboutissant généralement à des modifications du processus pense Agile est un processus et une solution miracle (dont il n'est ni l'un ni l'autre). Lisez le manifeste agile, écoutez les personnes qui ont lancé ce mouvement, comme Oncle Bob et Martin Fowler, et ne vous laissez pas emporter par la version absurde de "l'entreprise Agile".
En particulier, vous pouvez généralement vous contenter de TDD (Test Driven Development) sur du code scientifique , et il y a de bonnes chances que votre projet logiciel devienne diablement bien. En effet, les codes scientifiques performants ont généralement des interfaces ultra-utilisables, la performance constituant une préoccupation secondaire (et parfois concurrente), ce qui vous permet de vous en sortir avec un design plus "gourmand". TDD oblige en quelque sorte votre logiciel à être ultra-utilisable , car vous écrivez comment vous voulez que les choses soient appelées (idéalement) avant de les implémenter réellement. Cela force également de petites fonctions avec de petites interfaces qui peuvent rapidement être appelées simplement, en "entrée" / "sortie", et vous met dans une bonne position pour refactoriser en cas de changement des exigences.
Je pense que nous pouvons tous convenir que le numpy
logiciel de calcul scientifique est un succès. Leurs interfaces sont petites, super utilisables, et tout se joue bien ensemble. Notez que numpy
le guide de référence recommande explicitement TDD: https://docs.scipy.org/doc/numpy-1.15.1/reference/testing.html . J'ai déjà utilisé TDD pour le logiciel d'imagerie RSO (Synthetic Aperature Radar): je peux également affirmer que cela fonctionne extrêmement bien pour ce domaine particulier.
Mise en garde: la partie conception de TDD fonctionne moins bien dans les systèmes où une refactorisation fondamentale (par exemple, décider que votre logiciel doit être hautement concurrentiel) 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, utiliser TDD (pour piloter votre conception) serait une erreur ( vous pouvez toujours l'utiliser une fois que vous avez une conception préliminaire et que vous ne faites que "tester le premier développement". "). Il est important de réfléchir aux ressources et à la structure de votre application avant de vous lancer dans le code. TDD ne vous mènera jamais vers un système distribué hautement disponible.
Comment puis-je éviter de toujours avoir l'impression que si je reconstruisais complètement mon programme, je le ferais beaucoup mieux?
Compte tenu de ce qui précède, il devrait être assez évident qu'un design parfait est en fait impossible à réaliser. Il est donc difficile de rechercher un design parfait. Vous pouvez vraiment seulement vous approcher. Même si vous pensez pouvoir repenser à partir de zéro, il existe probablement encore des exigences cachées qui ne se sont pas manifestées. En outre, les réécritures prennent au moins le temps nécessaire au développement du code original. Ce ne sera presque certainement pas plus court, car il est probable que le nouveau design posera lui-même des problèmes imprévus. De plus, vous devrez ré-implémenter toutes les fonctionnalités de l'ancien système.
Une autre chose à considérer est que votre conception ne compte vraiment que lorsque les exigences changent .Peu importe à quel point la conception est mauvaise si rien ne change jamais (en supposant qu’elle soit entièrement fonctionnelle pour les cas d’utilisation actuels). J'ai travaillé sur une base comportant une instruction de commutation de 22 000 lignes (la fonction était encore plus longue). Était-ce un design terrible? Heck oui, c'était affreux. Avons-nous le réparer? Non, cela a bien fonctionné, et cette partie du système n'a jamais vraiment provoqué de crash ou de bugs. Cela n'a été touché qu'une fois au cours des deux années au cours desquelles j'ai participé au projet, et quelqu'un, vous l'avez deviné, a inséré un autre boîtier dans le commutateur. 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 le cas. Laissez la conception imparfaite telle qu'elle est, et si elle ne casse pas (ou se casse constamment), ne la corrigez pas. Alors peut-être que tu pourrais faire mieux ... mais est-ce que cela vaudrait la peine d'être réécrit? Qu'allez-vous gagner?
HTH.