web-dev-qa-db-fra.com

Comment les programmeurs rapides et sales savent-ils qu'ils ont bien compris?

Si vous demandez aux programmeurs pourquoi ils devraient écrire du code propre, la réponse numéro un que vous obtenez est la maintenabilité. Bien que cela soit sur ma liste, ma principale raison est plus immédiate et moins altruiste: je ne peux pas dire si mon nouveau code est correct s'il est trop sale. Je trouve que je me suis tellement concentré sur les fonctions individuelles et les lignes de code que lorsque je termine mon premier brouillon et que je recule pour regarder à nouveau la situation dans son ensemble, cela ne correspond parfois pas très bien. Passer une heure ou deux à refactoriser la propreté révèle fréquemment des erreurs de copier/coller ou des conditions aux limites qui étaient très difficiles à détecter dans le brouillon.

Cependant, certaines personnes pensent qu'il est parfois acceptable de vérifier intentionnellement du code sale dans l'intérêt des logiciels d'expédition, avec un plan pour "le nettoyer plus tard". Existe-t-il une technique pratique qui leur donne confiance dans l'exactitude de leur code lorsque la lisibilité est loin d'être idéale? Est-ce une compétence qui mérite d'être développée? Ou le manque de confiance dans le code est-il quelque chose que certaines personnes trouvent plus facile à accepter?

167
Karl Bielefeldt

Le code n'est probablement pas correct.

Cependant, cela n'a peut-être pas d'importance.

Rapide et sale peut être la bonne façon de procéder dans les situations où:

  • Le code a une courte durée de vie. Par exemple, vous transformez un tas de données en un format standard avec un programme ad-hoc.
  • L'impact négatif de l'échec est faible:
    • Les données que vous transformez ne sont pas critiques et les erreurs qu'elles contiennent peuvent être facilement corrigées
    • L'utilisateur final est un programmeur sympathique, qui raisonnera sur les messages d'erreur et les contournera, par exemple, en massant l'entrée.

Parfois, il n'est pas important que le code soit robuste et gère toutes les entrées imaginables. Parfois, il suffit de gérer les données connues que vous avez sous la main.

Dans cette situation, si les tests unitaires vous aident à obtenir le code écrit plus rapidement (c'est le cas pour moi), alors utilisez-les. Sinon, codez rapidement et sale, faites le travail. Les bugs qui ne se déclenchent pas n'ont pas d'importance. Les bugs que vous corrigez ou contournez à la volée n'ont pas d'importance.

Ce qui est absolument vital, c'est que vous ne diagnostiquez pas mal ces situations. Si vous codez rapidement et parce que le code ne sera utilisé qu'une seule fois, alors quelqu'un décide de réutiliser le code dans un projet qui mérite un meilleur code, ce code méritait plus d'attention.

100
slim

Ce n'est pas le cas. Je travaille actuellement sur une base de code créée par des programmeurs "rapides et sales" qui "la nettoieraient plus tard". Ils sont partis depuis longtemps, et le code persiste, grinçant vers l'oubli. codeurs Cowboy , en général, ne comprennent tout simplement pas tous les modes de défaillance potentiels que leurs logiciels peuvent avoir et ne comprennent pas les risques auxquels ils exposent l'entreprise (et les clients).

238
asthasr

D'accord, au risque d'être un appât négatif complet, je vais "défendre les démons" du point de vue opposé.

Je propose que nous, les développeurs, ayons tendance à trop nous préoccuper de choses comme les bonnes pratiques et la propreté du code. Je suggère que, bien que ces choses soient importantes, rien de tout cela n'a d'importance si vous ne livrez jamais.

Quiconque travaille dans ce domaine depuis un certain temps serait probablement d'accord pour dire qu'il serait possible de jouer avec un logiciel plus ou moins indéfiniment. Duke Nukem Forever, mes amis. Il arrive un moment où cette fonctionnalité de Nice-to-have ou ce travail de refactorisation si urgent doit être mis de côté et la chose devrait être appelée DONE.

J'ai combattu mes collègues à ce sujet à plusieurs reprises. Il y a TOUJOURS un autre Tweak, quelque chose d'autre qui "devrait" être fait pour qu'il soit "correct". Vous pouvez TOUJOURS trouver cela. À un moment donné, dans le monde réel, assez bon doit juste être assez bon. Aucun logiciel réel et réel d'expédition n'est parfait. Aucun. Au mieux, c'est assez bon.

103
Dan Ray

Ces programmeurs n'ont presque jamais sais ils ont bien compris, seulement croyez ainsi. Et la différence n'est peut-être pas facile à percevoir.

Je me souviens de la façon dont je programmais avant d'apprendre les tests unitaires. Et je me souviens de ce sentiment de confiance et de confiance à un niveau complètement différent après avoir exécuté ma première suite décente de tests unitaires. Je ne savais pas qu'un tel niveau de confiance dans mon code existait auparavant.

Pour quelqu'un qui n'a pas cette expérience, il est impossible d'expliquer la différence. Ainsi, ils peuvent même continuer à se développer en mode code et prière tout au long de leur vie, croyant bienveillant (et par ignorance) qu'ils font de leur mieux compte tenu des circonstances.

Cela dit, il peut en effet y avoir de grands programmeurs et des cas exceptionnels, quand on parvient vraiment à maintenir tout l'espace du problème dans son esprit, dans un état de flux complet. J'ai vécu de rares moments comme celui-ci, quand je savais parfaitement quoi écrire, le code m'a volé sans effort, je pouvais prévoir tous les cas spéciaux et les conditions aux limites, et le code résultant juste travaillé. Je ne doute pas qu'il existe des génies de la programmation qui peuvent rester dans un tel état de flux pendant de longues périodes ou même la plupart de leur temps, et ce qu'ils produisent est un beau code, apparemment sans effort. Je suppose que ces personnes pourraient ne pas ressentir le besoin d'écrire des tests unitaires minables pour vérifier ce qu'elles ont déjà savoir. Et si vous êtes vraiment un tel génie, ça va peut-être bien (même si, alors, vous ne serez pas autour de ce projet pour toujours, et vous devriez penser à vos successeurs ...). Mais sinon ...

Et avouons-le, les chances sont que vous n'êtes pas. Pour ma part, je sais que je ne le suis pas. J'ai eu de rares moments d'écoulement - et d'innombrables heures de chagrin et de chagrin, généralement causées par mes propres erreurs. Il vaut mieux être honnête et réaliste. En fait, je crois que les plus grands programmeurs sont pleinement conscients de leur propre faillibilité et de leurs erreurs passées, ils ont donc consciemment développé l'habitude de vérifier leurs hypothèses et d'écrire ces petits tests unitaires, pour se garder du bon côté. ("Je ne suis pas un grand programmeur - juste un bon programmeur avec de bonnes habitudes." - Kent Beck.)

85
Péter Török

Tests unitaires. C'est le seul moyen d'avoir confiance en n'importe quel code (sale ou non).

Sur une note latérale;

les raccourcis entraînent de longs retards (Pippin)

33
Tom Squires

Il est bon d’apprendre à accepter qu’aucun système logiciel d’une complexité raisonnable ne sera parfait, quels que soient les tests unitaires et les ajustements de code effectués. Un certain degré de chaos et de vulnérabilité à l'inattendu se cachera toujours dans le code. Cela ne signifie pas qu'il ne faut pas essayer de produire un bon code ou de mener des tests unitaires. Ce sont, bien sûr, importants. Il y a un équilibre à rechercher et cela variera d'un projet à l'autre.

La compétence à développer consiste à comprendre quel niveau de "perfection" doit être utilisé pour un projet particulier. Par exemple, si vous écrivez une application de dossiers médicaux électroniques avec un calendrier de projet de 12 mois, vous voudrez consacrer beaucoup plus de temps aux tests et vous assurer que votre code est maintenable que vous le feriez pour une application Web d'enregistrement de conférence unique. qui doit être déployé d'ici vendredi. Des problèmes surviennent lorsque quelqu'un qui exécute l'application EMR devient bâclé ou que l'application d'enregistrement n'est pas déployée à temps parce que le programmeur est trop occupé à peaufiner le code.

15
jfrankcarr

Rapide et sale est parfaitement bien dans un sous-système. Si vous avez une interface bien définie entre votre merde et le reste du système, et un bon ensemble de tests unitaires qui vérifient que votre code laid et rapide fait la bonne chose, cela peut être parfaitement bien.

Par exemple, vous avez peut-être un hack hideux d'expressions régulières et de décalages d'octets pour analyser certains fichiers provenant d'un tiers. Et supposez que vous ayez un test indiquant que le résultat que vous obtenez de l'analyse des fichiers d'exemple est ce que vous attendez. Vous pouvez nettoyer cela pour que vous puissiez ... Je ne sais pas, réagir plus rapidement quand un tiers change de format de fichier? Cela n'arrive pas assez souvent. Il est plus probable qu'ils passeront à une toute nouvelle API et vous jeterez l'ancien analyseur et en connecterez une nouvelle qui soit conforme à la même API, et le tour est joué.

Lorsque rapide et sale devient un problème, c'est lorsque votre architecture est rapide et sale. Votre objet de domaine principal doit être bien pensé et vos interfaces, mais les bords de votre système peuvent généralement être désordonnés sans jamais avoir à payer le piper.

11
Kevin Peterson

Voici l'histoire d'un programmeur rapide et sale que je connais.

J'ai connu une personne qui considère les tests unitaires comme une perte de temps. Après de nombreuses discussions, il en a finalement écrit un. Il consistait en une longue méthode saupoudrée de && et || et a renvoyé un booléen pour assertTrue. L'instruction s'étend sur 20 lignes. Là encore, il a écrit une classe où chaque méthode avait une ligne et une principale avait plus de 1000 lignes sans espaces blancs. C'était un mur de texte. Lorsque j'ai examiné son code et inséré de nouvelles lignes, il a demandé "pourquoi". J'ai dit "à cause de la lisibilité". Il soupira et les supprima. Il a mis un commentaire en haut "Ne le touche pas, ça marche!"

La dernière fois que je lui ai parlé, il a codé un site Web pour une entreprise. Il essayait de trouver un bug. Il avait passé les 3 derniers jours à faire cela pendant 8 heures par jour. Un peu plus tard, je lui ai de nouveau parlé, et il s'est avéré que son coéquipier a changé la valeur d'un littéral et ne l'a pas mis à jour ailleurs. Ce n'était pas une constante. Il a donc également changé les autres littéraux afin que son bug soit corrigé. Il s'est plaint du code de spaghetti de son coéquipier. Il m'a dit "Haha, ne savons-nous pas tous ce que c'est que de rester éveillé toute la nuit avec le débogueur, de ne pas dormir sur un mauvais bug".

De plus, il pense que lire des livres de programmation et des blogs est inutile. Il dit: "commencez simplement à programmer". Il fait ça depuis 12 ans et il pense qu'il est un excellent programmeur./facepalm


En voici encore plus.

Une autre fois, nous écrivions une classe DatabaseManager pour notre application Web. Il y a mis tous les appels de base de données. C'était une classe de Dieu avec plus de 50 méthodes pour chaque chose imaginable. J'ai suggéré de le diviser en sous-classes car tous les contrôleurs n'ont pas besoin de connaître chaque méthode de base de données. Il n'était pas d'accord, car il était "facile" de n'avoir qu'une seule classe pour toute la base de données et il était "rapide" d'ajouter une nouvelle méthode chaque fois que nous en avions besoin. Au final, DatabaseManager avait plus de 100 méthodes publiques, de l'authentification de l'utilisateur au tri des emplacements de sites archéologiques.

9
siamii

Ma leçon à éviter rapide et sale était quand j'avais six mois pour livrer ce qui était estimé (sous-estimé) à l'équivalent d'un an de travail. J'ai décidé de rechercher des méthodologies avant de commencer le travail. Au final, j'ai investi trois mois de recherche et j'ai pu livrer dans les trois mois restants.

Nous avons obtenu de gros gains en identifiant des fonctionnalités communes et en créant les bibliothèques requises pour gérer ces exigences. Je vois toujours des codeurs écrire leur propre code lorsqu'il existe des routines de bibliothèque disponibles. Ces codeurs réécrivent souvent, ou au mieux coupent-collent, le même code lorsqu'ils ont besoin de résoudre le même problème plus tard. Les corrections de bugs n'attrapent invariablement que certaines des copies de code.

Un développeur a donné une réponse révélatrice lorsque je lui ai demandé d'utiliser le code de la bibliothèque: "N'est-ce pas de la triche? J'ai dû écrire tout mon propre code à l'école."

7
BillThor

Dans certains cas, je suppose qu'il pourrait y avoir une grande suite de tests de régression qui trouveront "tous" les bogues et vérifieront le comportement, permettant ainsi une technique de codage rapide et sale. Mais la plupart du temps, c'est juste une mauvaise planification de projet et un gestionnaire qui pense qu'il est plus important de le faire que de le faire correctement.

Et oubliez "nettoyez-le plus tard", cela n'arrive jamais. Dans les rares cas où cela se produit, le programmeur aura oublié la majeure partie du code, ce qui rend le travail beaucoup plus cher que s'il l'avait fait correctement la première fois.

6
Fredrik

Le produit est expédié.

Le code n'existe pas dans le vide. J'ai subi un chagrin indescriptible en luttant contre les conséquences d'un codage rapide et sale et en cowboy. Mais parfois, la finition du produit est la priorité, sans trouver comment écrire le meilleur code. En fin de compte, si le produit est livré et fonctionne assez bien, les utilisateurs et les clients ne sauront pas ou se soucieront de la "mauvaise" qualité du code à l'intérieur, et j'admettrai qu'il y a eu des moments où je ne me souciais pas du tout de "l'obtenir". droit "tant que je l'ai sorti de la porte.

Oui, ceci dans un problème d'organisation et "ne devrait jamais arriver". Mais si vous écrivez du code dans une organisation mal gérée et fortement guidée par les délais, au niveau du programmeur individuel, les options sont limitées.

6
Suboptimus

Je ne pense pas qu'ils puissent honnêtement dire qu'ils ont bien fait si ce n'est pas facile à maintenir. S'ils admettent qu'ils doivent "le nettoyer plus tard", alors il y a probablement quelque chose qu'ils n'ont pas suffisamment réfléchi. Le tester à fond ne découvrira vraiment aucun problème avec du code sale.

Personnellement, je ne viserais pas à développer l'habileté à "écrire du code sale" et à avoir confiance en son exactitude. Je préfère écrire du code approprié la première fois.

5
Bernard

Comment savent-ils qu'ils ont bien compris? Le test est la réponse simple.

Si leur code a été testé à fond par une bonne équipe d'AQ et qu'il passe, alors je dirais qu'ils l'ont bien compris.

Écrire du code rapide et sale n'est pas quelque chose qui devrait être fait comme une habitude, mais en même temps, il y a des occasions où vous pouvez passer 20 minutes à écrire du code qui peut être classé comme sale ou 4 heures à refactoriser beaucoup de code pour le faire correctement. Dans le monde des affaires, parfois 20 minutes suffisent pour faire le travail et lorsque vous faites face à des délais rapides et sales, peut être la seule option.

J'ai moi-même été aux deux extrémités de cela, j'ai dû corriger le code sale et avoir dû écrire le mien afin de contourner les limites d'un système dans lequel je développais. Je dirais que j'avais confiance dans le code que je écrit parce que bien qu'il soit sale et un peu piraté, je m'assurais parfois qu'il était minutieusement testé et qu'il comportait beaucoup de gestion des erreurs intégrée, donc si quelque chose tournait mal, il ne détruirait pas le reste du système.

Lorsque nous regardons ces programmeurs rapides et sales, nous devons nous souvenir d'une chose, un client ne paie généralement pas tant qu'il n'a pas le produit, s'il est expédié et qu'il passe en test UAT et trouve les bogues à partir d'un code rapide et sale, c'est un beaucoup moins de chances qu'ils se retirent quand ils ont un produit presque fonctionnel devant eux, mais s'ils n'ont rien et que vous leur dites "vous l'aurez bientôt, nous réparons juste x" ou "cela a été retardé parce que nous devions obtenir y fonctionnant parfaitement "ils sont plus susceptibles d'abandonner et de partir avec un concurrent.

Bien sûr, comme cette image le montre, personne ne devrait sous-estimer le danger d'un code rapide et sale! enter image description here

5
Purplegoldfish

Je ne pense pas que vous devriez même commencer à emprunter cette voie. Rapide et sale pourrait vous donner l'avantage temporel de finir plus vite, mais vous payez toujours décuplé pour le faire à la fin.

4
Raku

À mon avis, apprendre à juger le code Q&D pour l'exactitude n'est pas une compétence qui mérite d'être développée car c'est juste une mauvaise pratique. Voici pourquoi:

Je ne pense pas que "rapide et sale" et "meilleures pratiques" vont de pair. De nombreux codeurs (moi y compris) ont lancé du code rapide et sale à la suite d'un biais dans le triple contraintes . Quand je devais le faire, c'était généralement le résultat d'un fluage de portée combiné à une échéance qui approche sans cesse. Je savais que le code que je vérifiais était nul, mais il crachait des sorties appropriées compte tenu d'un ensemble d'entrées. Très important pour nos parties prenantes, nous avons expédié à temps.

Un coup d'œil à l'original CHAOS Report montre clairement que Q&D n'est pas une bonne idée et tuera le budget plus tard (soit en maintenance soit pendant l'expansion). Apprendre à juger si le code Q&D est correct est une perte de temps. Comme l'a dit Peter Drucker, "Il n'y a rien d'aussi inutile que de faire efficacement ce qui ne devrait pas être fait du tout".

4
Trav

Je ne peux pas dire si mon nouveau code est correct s'il est trop sale.

"Sale" signifie différentes choses pour différentes personnes. Pour moi, cela signifie principalement compter sur des choses sur lesquelles vous savez que vous ne devriez probablement pas compter, mais sur lesquelles vous pouvez également vous attendre à travailler à court terme. Exemples: en supposant qu'un bouton mesure 20 pixels de haut au lieu de calculer la hauteur; coder en dur une adresse IP au lieu de résoudre un nom; compter sur un tableau à trier car vous savez qu'il l'est, même si la méthode qui fournit le tableau ne le garantit pas.

Le code sale est fragile - vous pouvez le tester et savoir qu'il fonctionne maintenant, mais c'est un très bon pari qu'il se cassera à un moment donné dans le futur (ou bien forcer tout le monde à marcher sur des œufs) de peur de le casser).

3
Caleb

Au risque de paraître un peu controversé, je dirais que personne vraiment SAIT que leur code est 100% correct et 100% sans erreur. Même lorsque vous avez une très bonne couverture de test et que vous appliquez rigoureusement les bonnes pratiques BDD/TDD, vous pouvez toujours développer du code qui contient des erreurs, et oui qui peut même contenir des effets secondaires!

Le simple fait d'écrire du code et de supposer qu'il fonctionne implique une confiance excessive de la part du développeur quant à ses propres capacités, et que lorsque des problèmes surviennent (ce qu'ils feront inévitablement), l'effort de débogage et de maintenance du code sera coûteux, surtout si un autre développeur a besoin pour conserver le code plus tard. La vraie différence est faite en appliquant de bonnes pratiques d'ingénierie logicielle, qui garantissent que vous pouvez être sûr que votre code est susceptible de fonctionner la plupart du temps et que si vous rencontrez une erreur, il est plus probable qu'il soit plus facile de déboguer et beaucoup moins coûteux à modifier et à maintenir indépendamment de la personne qui travaillera sur ce code plus tard.

Le point saillant est qu'un code bien factorisé et bien testé permettra à AUTRES d'avoir confiance en votre code, ce qui est dans la plupart des cas plus important que votre propre confiance.

3
S.Robins

Les bons programmeurs (Quick & Dirty et autres) n'ont pas l'orgueil de supposer qu'ils ont bien compris. Ils supposent que tous les grands systèmes ont des bogues et des failles, mais qu'à un moment donné, ils pourraient être suffisamment bien testés et examinés pour avoir un risque ou un coût d'échec suffisamment faible pour que le code puisse être expédié.

Alors pourquoi ces programmeurs, appelés Quick & Dirty, existent-ils? Mon hypothèse est la sélection darwinienne. Les programmeurs qui expédient du code exploitable rapidement, expédient occasionnellement avant la compétition, ou le budget est épuisé, ou l'entreprise fait faillite. Par conséquent, leurs entreprises utilisent toujours de nouveaux programmeurs pour se plaindre du désordre qui doit être nettoyé. Le soi-disant code propre est également livré, mais pas suffisamment bien pour entraîner l'extinction des codeurs Quick & Dirty.

2
hotpaw2

Si le code sale est bien testé, il peut être fiable. Le problème est que les tests unitaires de code sale sont généralement très difficiles et encombrants. C'est pourquoi TDD est si bon; il révèle et élimine la saleté et les odeurs. De plus, les tests unitaires sont souvent la première chose à souffrir du temps perdu. Donc, si le gars le plus propre a jamais fait le code le plus propre qu'il ait jamais fait, je ne lui ferais toujours pas confiance un peu, s'il omettait les tests unitaires en raison du temps rassuré.

2
Morten

On peut probablement penser qu'une partie non optimale d'un code ne pourrait faire aucune différence, en raison de la courte durée de vie, du faible impact sur les affaires ou du peu de temps pour le faire. La bonne réponse est que vous ne savez pas vraiment. Chaque fois que j'écoute quelqu'un dire que "c'est une petite fonctionnalité", ou "faisons-le aussi vite et aussi simplement que possible" et ne consacre pas suffisamment de temps à réfléchir à la bonne conception, les deux seules choses qui se produisent réellement et plus sont:

1-) Le projet s'agrandit et la motivation de l'équipe diminue, en travaillant sur du code plein de "points". Dans ce cas, le projet est susceptible de prendre une voie rapide vers le chaos.

2-) Le projet devient connu comme une solution non optimale et son utilisation commence à être découragée, au profit d'une nouvelle solution ou d'un refactoring aussi cher qu'une nouvelle solution.

Essayez toujours de faire le meilleur code possible. Si vous n'avez pas assez de temps, expliquez pourquoi vous en avez besoin de plus. Ne vous mettez pas en danger avec un travail mal fait. Soyez toujours un meilleur professionnel. Personne ne peut vous punir pour cela si vous êtes raisonnable. S'ils le font, ce n'est pas là que vous devriez travailler.

0
Thiago Gama

Discutez avec la personne âgée et évaluez l'impact des échecs, le cas échéant. Par exemple, une situation où vous pouvez corriger les problèmes de nettoyage prend 1 jour et un code robuste nécessite une modification de conception et d'architecture qui peut prendre de 4 à 6 mois + temps de validation supplémentaire pour valider complètement tous les workflows impactés par la modification de conception.

Nous devons également prendre une décision basée sur le Temps + Capacité + Priorités dans la liste. Une bonne discussion au sein de l'équipe avec des personnes âgées ou des personnes ayant une expérience plus élevée peut aider à atterrir sur une décision qui correspond le mieux à l'équipe et à son résultat.

Le code propre est la première et principale approche où, en tant que code sale pour enregistrer les escalades, les décisions go/no go des clients, montrent les bouchons, la réputation de l'organisation en jeu et bien d'autres encore où le code sale se transforme en code propre.

0
Mendy