it-swarm.dev

Comment gérez-vous le code laid que vous avez écrit?

Votre client vous demande donc d'écrire du code, alors faites-le. Il modifie ensuite les spécifications sur vous, comme prévu, et vous implémentez avec diligence ses nouvelles fonctionnalités comme un bon petit garçon. Sauf que les nouvelles fonctionnalités sont en conflit avec les anciennes fonctionnalités, alors maintenant votre code est un gâchis. Vous vraiment voulez revenir en arrière et le réparer, mais il continue de demander de nouvelles choses et chaque fois que vous finissez de nettoyer quelque chose, cela se termine à nouveau.

Que faire? Arrêtez d'être un maniaque du trouble obsessionnel-compulsif et acceptez simplement que votre code va finir en désordre, peu importe ce que vous faites, et continuez de vous attaquer aux fonctionnalités de cette monstruosité? Enregistrer le nettoyage pour la version 2?

89
mpen

Obtenez un autre emploi et laissez d'autres personnes s'en occuper. Muahahahhahahaa.

.....

Je rigole. :)

Mais en toute sincérité: remplissage d'estimation est votre ami. Je fais généralement une estimation réaliste décente, puis je double. Cela peut sembler excessif, et parfois c'est le cas, mais il vaut mieux surestimer un peu et même avoir l'air un peu lent parfois - que de laisser de mauvaises impressions en produisant du code bogué et en faisant toujours exploser vos estimations. Et bien sûr, vous contractez des dettes techniques en laissant la base de code devenir hacky.

Un autre conseil (connexe): estimez toujours en apparence minuscule, aucune tâche évidente pour un bloc de taille décente. Disons, par exemple - un élément dont vous êtes presque sûr qu'il ne s'agira que d'un simple changement de 30 secondes sur une ligne - donnez-lui 1 heure (ou peut-être quel que soit le bloc de temps le plus bas sur votre feuille de temps ou système CR, par exemple 15 minutes/0,25 heure) . Et donnez des blocs d'une demi-journée ou d'un jour pour les articles légèrement plus gros mais toujours relativement triviaux.

La raison en est principalement psychologique: je trouve que si vous avez l'habitude de pirater rapidement de petits changements, le travail semble précipité, et vous ne finissez jamais par vous asseoir, faire le point et refactoriser des choses qui doivent être refactorisées. De plus, sur le plan pratique: des changements petits mais non triviaux éclatent parfois, et vous ne voulez pas vous sentir constamment en retard et éteindre les bugs. Cela fait partie des raisons pour lesquelles les bases de code deviennent hacky au fil du temps.

Enfin, souvenez-vous toujours que les gens n'ont pas à savoir que vous remplissez quelque peu vos estimations. Tant que vous êtes un développeur compétent et que vous travaillez à un rythme décent, ce rembourrage ne sera pas perceptible. ie Ne dites pas au PHB "Mon estimation initiale est que ça va prendre deux heures, mais donnez-moi une demi-journée". Dites-lui simplement "Je pense que cela prendra environ une demi-journée." et laissez-le là.

41
Bobby Tables

Surestimer délibérément le temps nécessaire à vos prochaines fonctionnalités. Utilisez ce temps supplémentaire pour nettoyer.

Vous ne serez jamais en mesure de justifier la maintenance, et le client en a besoin malgré tout, alors donnez-lui le médicament amer (coûts légèrement accrus pour les prochaines fonctionnalités) afin qu'il puisse s'améliorer.

66
Frank Shearar

Essayez de faire une refonte appropriée tout en intégrant de nouvelles fonctionnalités. Il n'y en a pas plus tard. Sans la refonte, vous ajoutez constamment de plus en plus de friction pour de nouveaux changements et de nouvelles fonctionnalités.

À un moment donné, vous arriverez à un arrêt quasi absolu où tout semble prendre du temps. La plupart des entreprises optent probablement pour la grande réécriture à ce stade, la version 2. Elle a une économie assez médiocre et c'est un bon moment pour votre client d'essayer une autre partie de développement s'il le souhaite.

Une refonte/refactorisation appropriée peut protéger l'investissement de vos clients et maintenir les choses durables. Vous devez l'intégrer. Optimiser pour le changement, voyager léger.

11
Joppe

Avec tous les commentaires sur la surestimation, je pense qu'il y a une quantité modeste de point (enfin une opportunité) manquée.

Il ne s'agit pas d'estimer le temps nécessaire pour effectuer le changement (juste), puis d'en ajouter, il s'agit d'estimer le temps nécessaire pour modifier le code (refactoriser!) Pour l'amener à un point où le changement peut être effectué en toute sécurité et ensuite effectuer le changement (probablement un peu coincé). Ok, cela revient à la même chose ... mais il n'est pas question de fudging ou d'étirement ou de surestimation, c'est simplement une question de dire que pour ce faire, je dois d'abord le faire et c'est combien de temps cela prendra au total. La clé ici est que vous travaillez sur les parties du système dont le changement dépend et pas plus - s'il y a un code horrible ailleurs ... difficile, attrapez-le lorsque vous êtes là.

Pour revenir un peu à la question d'origine - après de nombreuses années, cela revient à moi, lorsque vous implémentez quelque chose à moins que vous sachez (ne croyez pas, n'attendez pas (suspect?), Ne pensez pas mais savoir) que des choses supplémentaires sont également nécessaires, vous devez faire ce dont vous avez besoin pour mettre en œuvre cette exigence et non plus de manière aussi ordonnée et élégante que possible.

Lorsque vous venez d'implémenter la chose suivante - un peu plus tard - vous prenez les mesures nécessaires pour amener la base de code (et la base de données et autres) à l'état nécessaire pour implémenter cette fonctionnalité de la manière la plus ordonnée et élégante possible. Cette refactorisation est l'endroit où vous traitez le désordre qui survient naturellement à mesure qu'un projet évolue - et, espérons-le, évitez de créer plus de désordre (ou du moins de maintenir le niveau cohérent).

L'un des domaines de discussion ici est la "dette technique" - c'est comme un découvert, vous devez le rembourser et plus vous le laissez, plus vous accumulerez d'intérêts (dans ce cas, le temps nécessaire pour corriger) - ce qui vous donne une bonne argument pour passer une partie de votre temps à minimiser la dette technique.

C'est également là que les tests unitaires et autres tests automatisés commencent à entrer (si je pouvais faire aussi bien que je dis que je suis assez sûr que je serais une personne plus heureuse!) Combinés avec un serveur de build approprié (qui peut exécuter au moins certains de vos tests). Combinés à ceux-ci - mais de valeur en soi - sont des modèles comme l'injection de dépendance et l'inversion de contrôle (jamais vraiment sûr à quel point les "mêmes" ces deux sont), car ils facilitent le changement de plomberie et donc traitent les changements de isolement.

Enfin - rappelez-vous, si ce n'est pas cassé, ne le réparez pas. Ranger votre code uniquement pour le ranger peut être satisfaisant mais c'est aussi une opportunité d'introduire des erreurs, alors que cela peut être douloureux si vous n'avez pas besoin de le changer et que vous ne le construisez pas dessus peut-être vaut-il mieux laisser certains morceaux seuls - la possibilité de réparer ou de remplacer finira par tourner!

6
Murph

1) Le bon contrôle des changements est votre ami

Si le client modifie la spécification, c'est bien son droit, mais c'est un changement et il doit être facturé (ou chiffré de la manière appropriée à la structure/relation du projet).

L'estimation de ce changement devrait inclure le coût du refactoring nécessaire . Le client peut bien reculer devant ce qui semble être un coût élevé, mais à ce stade, vous devez lui expliquer que parce que le code est déjà à moitié écrit, il y a des éléments qui doivent être réécrits pour s'assurer qu'il est robuste et supportable à l'avenir et que si ce n'est pas fait, il aura probablement des problèmes avec le support futur ou les changements deviendront encore plus chers.

2) Le refactoring doit être effectué de telle sorte qu'il offre un véritable avantage à long terme au client

Lorsque vous envisagez de refactoring, vous devez toujours considérer ce qui est réellement nécessaire et ce qui est important et vous assurer que le travail de refactoring offre un véritable rapport qualité-prix à long terme.

Après tout, nous devons faire ces choses pour que le code reste extensible et supportable à moyen/long terme pour garantir que l'investissement du client reste valide plutôt que hors de toute recherche de perfection théorique. Le travail de refactorisation (et les estimations correspondantes) devrait être fait avec cela comme champ d'application, et pas seulement parce que vous pensez maintenant qu'il pourrait y avoir une meilleure façon de le faire.

4
Jon Hopkins

Certains programmeurs suggèrent qu'un moyen de contrôler ce problème avec les clients consiste à demander au client de signer et d'autoriser la spécification initiale. ALORS, quand ils demandent un changement d'exigence qui n'est pas dans la spécification initiale, vous leur dites que vous devez parcourir le contrat et le calendrier du projet afin de calculer les coûts supplémentaires et les délais, puis faire une annexe au contrat. Apparemment, cela fait des merveilles en empêchant les clients d'insister sur de nouvelles fonctionnalités (imprévues).

3
Jas

J'ai le commentaire suivant dans une base de code sur laquelle je travaille actuellement:

/*
 * Every time I see this function, I want to take a shower.
 */

Je sais très bien la situation que vous décrivez. Ce que je fais, c'est essayer (de mon mieux) d'attendre que les choses se calment et que tout type de "fluage" ait "glissé" tout ce qu'il va faire. À ce moment-là, vous avez probablement sorti quelque chose utilisable, et vous pouvez prendre un certain temps pour nettoyer les choses et implémenter les choses un peu différemment.

Vous ne pouvez pas courir à plusieurs reprises pour nettoyer de nombreux petits dégâts. Cela triple simplement votre travail et votre frustration. Attendez qu'il devienne un gâchis plus gros, mais à peine mouvant, puis vous pouvez faire quelque chose.

3
Tim Post

Ma préférence est d'éviter cette situation en premier lieu.

Tout dépend de la façon dont vous lisez les spécifications. Il est facile de les considérer comme des tablettes de pierre, mais en réalité, la plupart des spécifications changent. Lorsque vous concevez votre code, déterminez la probabilité que chaque partie de la spécification change. Au fil du temps, vous deviendrez assez bon pour prédire cela.

Entrer dans le pétrin, l'expérience et le jugement est très important. Ecrivez-vous de nouveaux bugs à cause de ce code spaghetti? prend-il plus de temps à mettre en œuvre? ceux-ci indiqueraient de faire un refactor tactique.

pour l'avenir, il semble que vous deviez travailler en partenariat avec votre client. En leur disant: "regardez ce produit se développe considérablement au-delà des spécifications d'origine. Alors que la conception originale était bonne pour ce niveau, l'expansion dans la direction X et les directions Y ont besoin d'une restructuration dans la conception" bien gérée, et vous obtiendrez même votre client pour le payer.

2
Michael Shaw

Chargez à l'heure et s'il veut des changements, dites que c'est bien mais incorporez le temps nécessaire pour écrire un bon code dans l'équation. Souvenez-vous également que l'écriture d'un code plus net est rentable à long terme lorsque vous devez le maintenir. Gagner du temps maintenant pourrait vous coûter plus tard.

2
Craig

Je pense que l'écriture de logiciels doit aller de pair avec les besoins de l'entreprise. S'il s'agit d'un projet jetable (comme un prototype qui doit être construit en une semaine, avec de nouvelles entrées qui arrivent tous les jours), alors il n'y a pas besoin de s'inquiéter de la maintenabilité du code et d'autres choses - le temps est crucial et il vous suffit de le faire Poussez votre code hors de la porte aussi vite que possible.

Mais si vous écrivez une application à long terme, il est logique de considérer tout cela, car il y a un impact considérable sur le temps qu'il faut pour créer de nouvelles fonctionnalités, pour corriger les bogues existants, pour s'intégrer dans d'autres applications et d'autres choses - et cela se traduit par un impact sur les entreprises (en raison du temps nécessaire plus tard et des coûts plus élevés).

Il est donc préférable de sensibiliser le décideur aux coûts réels de la non-refactorisation du code chaque fois que cela est nécessaire - d'après mon expérience, si les coûts et l'impact temporel des deux options sont expliqués en termes mesurables au propriétaire de la décision, alors la décision peut être un aucune évidence. Ne vous attendez pas à ce que les gens vous disent "ouais, allez-y, écrivez du beau code, même si cela prend deux fois plus de temps et ne me donne aucun avantage supplémentaire". Cela ne fonctionne tout simplement pas de cette façon.

1
Roopesh Shenoy

Faites-en partie de votre processus, je l'appelle "refactoring extrême" et ça va être gros! ;) Faites juste des trucs rapidement et quand suffisamment de nouvelles fonctionnalités ont été ajoutées pour qu'il y ait du tissu cicatriciel, refactorisez-le. Demandez-vous continuellement "Maintenant, si j'avais recommencé à zéro, comment aurais-je pu le faire"

Les gens qui pensent pouvoir concevoir et penser à tout à l'avance se trompent le plus, vous (et votre client) apprenez toujours des choses au fur et à mesure. Utilisez ces leçons.

Comme vous êtes un bon programmeur, vous pourrez refactoriser assez rapidement et en le faisant continuellement, le code commencera à prendre sa "forme appropriée", ce qui signifie qu'il deviendra plus flexible avec moins de dépendances.

Les clients pourraient être vexés s'ils savaient que vous "perdez du temps" à retravailler des trucs afin que cela évite de demander/dire et d'être très rapide à ce sujet.

Le code développé de cette manière vous fera gagner beaucoup de temps au final et facilitera de plus en plus l'ajout de nouvelles fonctionnalités.

Je dirais également que l'une des principales raisons d'un mauvais code est la crainte de certains programmeurs de procéder à un refactoring structurel plus important, et plus vous attendez, pire c'est.

1
Homde

Comptez sur une puissance supérieure

Je ne veux pas dire prier. Je veux dire, assurez-vous qu'il y a un homme d'affaires (c.-à-d. Chef de projet ou équivalent) que vous pouvez placer comme rembourrage entre vous et le client. Si le client demande trop, laissez le gars d'affaires poser le pied et être prêt à manier le "c'est faisable mais je ne sais pas si cela correspond à la portée des spécifications, voir [homme d'affaires]".

Dans un flux de projet normal, les spécifications générales doivent être gelées avant qu'un développement sérieux n'ait lieu.

De nombreux clients continueront de rechercher des changements/améliorations/améliorations tant que vous les laissez. Beaucoup abuseront de cette capacité au maximum car cela leur donne l'impression de tirer le meilleur parti de leur argent (même si cela sabote votre projet).

Demandez à une personne dédiée de perfectionner et de geler la spécification dès le début et de la faire appliquer plus tard.

Il n'y a rien de mal à faire un peu plus pour un peu de bon karma avec le client, mais soyez prêt à vous en remettre à une puissance plus élevée lorsqu'il devient incontrôlable. Si la spécification nécessite une quantité ridicule de changements, il est peut-être temps de revenir dans la boucle commerciale et de réévaluer le contrat et/ou d'ajouter des ajouts au contrat (avec une compensation monétaire équitable).

Le fait que vous rencontriez ce problème n'a pas grand-chose à voir avec la façon dont vous codez. C'est un signe que votre chef de projet est sous-utilisé sur le projet (que ce soit votre faute, sa faute ou les deux).

Comme d'autres l'ont dit dans de nombreuses réponses, l'ajout d'un tampon de temps pour les imprévus est également nécessaire sur tout projet, mais il doit être déterminé à huis clos avant que la spécification ne soit gelée et livrée au client par le PM.

1
Evan Plaice

Réponse la plus simple. J'arrêterais de coder de toute sorte, jusqu'à ce qu'il ait une spécification finale pour exactement ce qu'il/elle veut à partir de maintenant.

Ensuite, ils doivent hiérarchiser cette liste de fonctionnalités, etc., pour confirmer quels éléments doivent avoir en ce moment, et ceux qui peuvent être effectués plus tard ....

En utilisant vos expériences pour déterminer le temps/coût de chaque fonctionnalité, puis dites-leur, s'ils le veulent, cela prendra x quantité de temps et d'argent.

Vous traitez avec le grand crime du fluage de la portée des fonctionnalités, et ils continueront sans cesse d'ajouter des fonctionnalités, jusqu'à ce que rien ne soit jamais fait ou mal fait.

Dites-leur une fois que vous avez une liste finale, que vous ferez des modifications futures, comme ils préfèrent, mais que vous devez vous concentrer sur le top 15/20 qu'ils doivent avoir en ce moment.

Ensuite, en fonction du temps écoulé, dites-leur qu'après la publication de cette version, vous serez prêt à discuter/réfléchir à la prochaine version.

Une fois qu'une décision finale a été prise quant à ce qui doit être fait pour la version actuelle, toutes les discussions/idées/suggestions doivent être arrêtées à 100%.

S'il obtient des idées à l'infini, dites-lui de les noter, dans leur liste de fonctionnalités pour la prochaine version, et laissez-vous concentrer sur la fourniture des fonctionnalités les plus importantes dont ils ont besoin maintenant.

S'ils continuent de perdre votre temps, continuez de changer d'avis. Ensuite, je cesserais de travailler sur le projet et travaillerais sur d'autres projets jusqu'à ce qu'ils aient finalisé leurs décisions.

C'est difficile à faire, mais le fluage de la portée des fonctionnalités est tellement destructeur de temps, d'énergie, de motivation et de pensée claire.

0
crosenblum

Du point de vue d'un projet complet:

Apprenez du code avec votre équipe, voyez ce qui peut être refactorisé et réutilisé la prochaine fois, puis allez prendre une bière.

Du point de vue du développement:

Expliquez patiemment pourquoi le développement s'est arrêté et expliquez pourquoi il ne peut pas continuer jusqu'à ce que toutes les spécifications soient sur la table et comprises. Ensuite, allez prendre une bière.

Du point de vue de la planification:

Demandez toutes les spécifications à l'avance et travaillez avec tout le monde pour avoir une compréhension claire du chemin de développement. Impliquez le client/les parties prenantes aussi étroitement que possible pour vous assurer que tout le monde sur la même page. Plus tard dans la soirée, prenez des bières pour tout le monde. Demain, lancez le projet.

0
Kevin

Tuez-le avec le feu.

Aka refactor dès que possible: par exemple lorsque le code laid vient de se précipiter pour une date limite, je voudrais refactoriser après la date limite parce que vous ne pouvez pas (ou ne devriez pas au moins) ajouter plus de fonctionnalités jusqu'à ce que le code existant soit maintenable, sinon cela va rendre encore plus difficile le débogage des futurs codes.

0
wildpeaks

La bonne conception initiale ne peut pas aider à éviter le problème. Et il est presque impossible (ou très-très difficile) de considérer toutes les futures exigences "peut-être". Donc, après un certain temps, le Big Re-factoring arrivera. Et la meilleure solution est de tout réécrire.

En quelques mots: au lieu de monter une tourelle sur la Ferrari rouge, repenser les exigences et construire un char.

0
duros

Écrivez des tests unitaires pour vos projets qui testent l'état actuel, puis refactorisez lorsque vous en avez le temps, de cette façon vous évitez de casser votre projet pendant que vous essayez de le nettoyer.

0
chiurox