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


88

Votre client vous demande alors d’écrire du code. Il modifie ensuite les spécifications sur vous, comme prévu, et vous implémentez ses nouvelles fonctionnalités avec diligence, comme un bon petit garçon. Sauf que ... les nouvelles fonctionnalités sont en conflit avec les anciennes. Votre code est donc en désordre. Vous voulez vraiment y retourner et le réparer, mais il continue à demander de nouvelles choses et chaque fois que vous avez fini de nettoyer quelque chose, tout se gâte à nouveau.

Que faire? Arrêtez d'être un maniaque des TOC et acceptez simplement que votre code finisse par vous gâcher, peu importe ce que vous faites, et continuez à vous concentrer sur les fonctionnalités de cette monstruosité? Enregistrer le nettoyage pour la version 2?


15
C'est une excellente question.
Walter

3
Je pense que c’est un bon endroit pour appliquer la règle des 80/20 .
Mark C

euh..n'écris pas de code moche en premier lieu?!
Roopesh Shenoy

8
@Roopesh: Ce n'est pas moche en premier lieu, c'est quand on continue à clouer des trucs dessus, ça devient moche. Avec les fonctionnalités ajoutées, vous réalisez que la structure de base aurait pu être conçue différemment pour mieux prendre en charge ces fonctionnalités. Et à ce stade, vous pouvez soit revenir en arrière et réécrire de gros morceaux de fond de teint, soit simplement ajouter la fonctionnalité. Généralement, il n’ya pas assez de temps pour revenir en arrière et réécrire la moitié de votre programme.
mpen

Ensuite, vous dites "concevoir avec changement". C'est facile à dire, mais lorsque certaines choses fondamentales changent parce que votre client ne sait pas vraiment ce qu'il veut et ne vous donne qu'une demi-spécification à l'avance, c'est un peu difficile.
mpen

Réponses:


41

Trouvez un autre emploi et laissez les autres s'en occuper. Muahahahhahahaa.

.....

Je rigole. :)

Mais sérieusement: le rembourrage d'estimation est votre ami. Je fais généralement une estimation réaliste décent, puis le double. Cela peut sembler excessif, et c'est parfois le cas, mais il vaut mieux surestimer un peu et même paraître un peu lent parfois - plutôt que de laisser de mauvaises impressions en transformant du code buggy en soufflant toujours vos estimations. Et bien sûr, vous contractez une dette technique en laissant la base de code se faire mal.

Un autre conseil (lié): Estimez toujours des tâches apparemment minuscules et sans complication à un bloc de taille décente. Par exemple, un élément dont vous êtes presque sûr sera un simple changement d'une ligne à 30 secondes, donnez-lui une heure (ou peut-être le bloc horaire le plus bas sur votre feuille de temps ou votre système CR, par exemple 15 min / 0,25 heure) . Et donnez des blocs d'une demi-journée ou d'une journée pour les articles un peu plus gros mais qui restent relativement triviaux.

La raison en est principalement psychologique: je trouve que si vous prenez l’habitude de modifier rapidement de petits changements, le travail semble fastidieux, et vous ne finissez jamais par vous asseoir, faire le point et refactoriser des éléments qui doivent être restructurés. En outre, sur le plan pratique, des changements mineurs, mais non triviaux, disparaissent parfois et vous ne voulez pas avoir constamment le sentiment d'être en retard sur votre calendrier et de vous éteindre. Cela explique en partie pourquoi les bases de code se font de plus en plus difficiles.

Enfin, souvenez-vous toujours que les personnes ne doivent pas savoir que vous complétez quelque peu vos estimations. Tant que vous êtes un développeur compétent et que vous travaillez à un rythme convenable, ce rembourrage ne sera pas perceptible. C'est-à-dire, ne dites pas au PHB "Mon estimation initiale est que cela 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 le laisser là.


12
+1 pour être méchant. ;)for(printf("MUHU"); 1; printf("HA"));
Mateen Ulhaq

1
@ muntoo: Il m'a fallu une seconde pour me rendre compte de ce que ça a ... n'a pas vu le for. Mignonne;)
mpen

4
Je suis sûr que cela dépend du responsable, mais vous n'avez pas nécessairement besoin de mentir. Le CTO et moi avons une compréhension; il sait que je peux donner une estimation raisonnable, mais avec une confiance d'environ 50%; si je mets un facteur de fudge, alors je peux donner la même estimation avec un niveau de confiance de 90%. Et il s'avère que, sur une longue période, la plupart des gens préfèrent les estimations fiables aux optimistes naïvement optimistes, même s'ils ne l'admettent pas ou ne s'en rendent pas compte. Il donne donc cette estimation pessimiste à son patron, sauf en cas d'urgence.
Aaronaught

2
La remarque selon laquelle rien ne prend moins d’une demi-heure environ est très bien faite. Même si un seul changement au code prend 5 minutes, il y a une surcharge de temps qui va avec.
Murph

2
@Murph - spot on. Je refuse toute estimation commerciale inférieure à une demi-journée. Au moment où le développeur a saisi le bon code, apporté les modifications, exécuté les tests unitaires, réussi la construction à tester et vérifié que l'intégrité physique était vérifiée, RIEN ne prend que 5 minutes.
Jon Hopkins

66

Surestimez 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 une maintenance, et le client en a besoin indépendamment. Vous devez donc lui donner le médicament amer (coûts légèrement supérieurs pour les fonctionnalités suivantes) afin qu'il puisse aller mieux.


+1 pour cela. Estimation du rembourrage FTW. Et en réalité, le même conseil est utilisé pour justifier la durée de la réparation et de la maintenance des bogues (en tout cas en interne: justifier le PHB, pas les clients, car vous dites que les clients ne s’en soucient pas).
Bobby Tables

5
Je pense que c'est aussi une façon raisonnable de régler le problème. Les souffrances qu’ils doivent supporter aux développeurs doivent être répercutées en tant que coûts supplémentaires. La direction et la force de vente doivent également adhérer à cette philosophie, faute de quoi les développeurs acquerront l’arbre et seront soumis à une aggravation constante des bases de codes.
le Tin Man

1
Oh, plus loin: absolument, l'idéal est une communication ouverte et honnête. Je suggère seulement un mécanisme d'adaptation quand ce n'est pas parfaitement réalisable. C'est une médecine à long terme comme tromperie.
Frank Shearar

3
Est-ce que cette estimation est complétée? Il semble que le temps soit venu d'implémenter une nouvelle fonctionnalité tout en conservant la qualité du code pour moi.
David Thornley

2
Je pense que c’est surtout la bonne approche, mais je la caractériserais différemment. Ils vous embauchent pour développer un code de qualité professionnelle. Cela signifie que vous devez intégrer à vos estimations le temps nécessaire pour "faire les choses correctement". Ne faites pas d’estimations basées sur le temps qu’il vous faudrait si vous restiez éveillé toute la nuit et déclariez «achevé» dès qu’il fonctionnait correctement la première fois. Cela peut signifier que dans une situation concurrentielle, vous serez parfois sous-estimé. C'est bon. Vous développerez une réputation de qualité et de cohérence et vous gagnerez. Joue le long jeu.
Brandon DuRette

11

Essayez de procéder à une nouvelle conception en intégrant de nouvelles fonctionnalités. Il n'y a pas plus tard. Sans la nouvelle conception, vous ajoutez constamment de plus en plus de friction pour les modifications et les nouvelles fonctionnalités.

À un moment donné, vous arrivez à un point d'arrêt presque parfait où tout semble prendre des siècles. La plupart des entreprises optent probablement pour la grande réécriture à ce stade, la version 2. La situation économique de ce dernier est plutôt médiocre et le moment est bien choisi pour votre client d’essayer une autre partie du développement s’il le souhaite.

Une nouvelle conception / refactorisation peut protéger l'investissement de vos clients et préserver la durabilité. Vous devez intégrer ceci. Optimiser pour le changement, voyager léger.


6

Avec tous les commentaires sur la surestimation, je pense qu’il manque un peu de point (une opportunité).

Il ne s’agit pas d’estimer le temps nécessaire pour effectuer le changement (juste) et d’en ajouter quelques-unes, mais plutôt d’estimer le temps nécessaire pour modifier le code (refactor!) Afin de le porter à un point où le changement peut être effectué en toute sécurité et ensuite effectuer les modifications. changer (probablement un peu ensemble ensemble). Ok, c’est la même chose ... mais il n’est pas question de tromper, d’étirer ou de surestimer, c’est simplement une question de dire que pour faire cela, 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 dépend le changement et pas plus - s'il y a du code horrible ailleurs ... dur, attrapez-le quand vous y êtes.

Pour revenir un peu à la question initiale - après de nombreuses années, cela revient à ceci pour moi, lorsque vous implémentez quelque chose à moins que vous ne sachiez (ne croyez pas, ne vous attendez pas (suspect?), Ne pensez pas, mais savez ) que Il est également nécessaire de faire ce qui est nécessaire pour mettre en œuvre cette exigence et de ne plus rien mettre d'aussi ordonné et élégant 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 ainsi de suite) à l'état requis pour implémenter cette fonctionnalité de manière aussi ordonnée et élégante que possible. Cette refactorisation vous permet de gérer le désordre qui survient naturellement au fur et à mesure de l'évolution d'un projet - tout en évitant, espérons-le, de créer davantage de désordre (ou du moins de préserver la cohérence du niveau).

L’un des sujets de discussion ici est la «dette technique» - c’est comme un découvert, vous devez le rembourser et plus vous le laissez longtemps, plus vous accumulerez d’intérêts (dans ce cas, le temps nécessaire pour les 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 à arriver (si je pouvais le faire aussi bien que je le sache, je suis à peu près certain que je serais une personne plus heureuse!), Associé à un serveur de construction approprié (pouvant au moins fonctionner de vos tests). Combinés à ceux - mais qui ont de la valeur en soi -, des modèles tels que l’injection de dépendance et l’inversion du contrôle (ne sachant jamais à quel degré sont les "mêmes" ces deux), car ils facilitent le changement de tuyauterie et permettent ainsi de gérer les modifications de isolement.

Enfin - rappelez-vous, si ce n'est pas cassé ne le répare pas. Nettoyer votre code uniquement pour le ranger peut être satisfaisant, mais c'est aussi une occasion d'introduire des erreurs, alors que cela peut être douloureux si vous n'avez pas besoin de le modifier et que vous ne le construisez pas, il vaut peut-être mieux laisser quelques bosses. seul - la possibilité de réparer ou de remplacer finira par tourner!


4

1) Le contrôle du changement est votre ami

Si le client modifie les spécifications, c'est bien, 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 de la refactorisation nécessaire . Le client peut bien craquer à ce qui semble être un coût élevé, mais vous devez lui expliquer que, comme le code est déjà à moitié écrit, certains éléments doivent être réécrits pour garantir sa robustesse et sa compatibilité dans le futur. s'il ne le fait pas, il aura probablement des problèmes avec le support ou les modifications deviendront encore plus onéreuses.

2) Le refactoring devrait être fait de telle sorte que le client bénéficie réellement d'un avantage à long terme

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

Après tout, nous devrions faire ces choses pour que le code reste extensible et supportable à moyen / long terme afin de garantir que l'investissement du client reste valable plutôt que de rechercher la perfection théorique. Le travail de refactoring (et les estimations correspondantes) doit être effectué avec la même portée, et pas seulement parce que vous pensez maintenant qu'il pourrait exister un moyen légèrement meilleur de le faire.


3

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


2
+1; Cela peut fonctionner, mais vous risquez également de vous aliéner en vous montrant trop rigide. Dans une certaine mesure, que vous puissiez le faire ou non dépend du type (taille) du projet et des attentes du client.
Ken Henderson

3

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 est d’essayer (de mon mieux) d’attendre que les choses se calment et que tout type de "fluage" ait "laissé filer" tout ce que cela va faire. À ce moment-là, vous avez probablement déjà sorti quelque chose d’utilisable, et vous pouvez prendre un peu de temps pour nettoyer les choses et les mettre en œuvre un peu différemment.

Vous ne pouvez pas courir nettoyer de nombreux petits dégâts à plusieurs reprises. Cela ne fait que tripler votre travail et votre frustration. Attendez qu'il devienne un désastre plus grand, mais qui ne bouge guère, et vous pourrez alors faire quelque chose.


2

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 penser à eux 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. Avec le temps, vous deviendrez assez bon pour prédire cela.

Une fois dans le pétrin, l'expérience et le jugement sont très importants. Vous écrivez de nouveaux bugs à cause de ce code spaghetti? est-ce que cela prend plus de temps à mettre en œuvre? ceux-ci indiqueraient faire un refactor tactique.

pour l'avenir, il semble que vous deviez travailler en partenariat avec votre client. En leur disant, "regardez ce produit est en train de s'étendre considérablement au-delà de la spécification d'origine. Alors que la conception d'origine était bonne pour ce niveau, élargissez-le dans la direction X et la direction Y a besoin d'une restructuration dans la conception" bien gérée, et vous obtiendrez même votre client à payer pour cela.


Je ne sais pas si je les considérerais comme des "bugs" ou non. Je fais de grands changements et, naturellement, tout commence à s'effondrer lorsque vous commencez à déchirer les fondations. Tout est réparable cependant. Je rappelle à mon client les coûts liés à des modifications de ce type régulièrement, mais il souhaite des "estimations" immédiates, que je ne peux tout simplement pas donner. Il n’est même pas possible de se garer avant de penser à toutes les modifications de conception à apporter, mais il ne comprend tout simplement pas cela. En tout cas, il paye et il ne se plaint pas trop.
mpen

2

Chargez à l'heure et s'il veut des changements, dites-le, mais intégrez le temps nécessaire pour écrire du code dans l'équation. N'oubliez pas non plus que l'écriture de code plus propre est rentable à long terme lorsque vous devez le conserver. Gagner du temps maintenant pourrait vous coûter plus tard.


Je charge par heure, mais le fait est que, même si je prends le temps d'écrire un "bon code", il devient rapidement obsolète, je me demande s'il y a un intérêt. Je pense que j'augmente les coûts en nettoyant constamment avant même que le projet ne se soit stabilisé.
mpen

1

Je pense que les logiciels d’écriture doivent 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 chaque jour), vous n'avez pas à vous soucier de la maintenabilité du code et d'autres tâches - le temps est crucial et il vous suffit de poussez votre code hors de la porte aussi vite que possible.

Mais si vous écrivez une application à long terme, il est logique de prendre tout cela en compte, car il y a un impact considérable sur le temps qu'il faut pour créer de nouvelles fonctionnalités, pour corriger des bugs existants, pour s'intégrer à d'autres applications et à d'autres éléments - et cela se traduit par un impact commercial (en raison du temps supplémentaire requis et du coût supplémentaire).

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 - selon mon expérience, si les coûts et l’impact temporel des deux options sont expliqués de manière mesurable au propriétaire de la décision, la décision peut alors être prise en compte. aucune évidence. Ne vous attendez pas à ce que les gens vous disent: "Allez, écris un beau code, même si cela prend deux fois plus de temps et ne me procure aucun avantage supplémentaire". Ça ne marche pas comme ça.


1

Faites-en une partie de votre processus, je l'appelle "refactoring extrême" et ça va être gros! ;) Il suffit de faire les choses rapidement et quand suffisamment de nouvelles fonctionnalités ont été ajoutées qu'il y a un tissu cicatriciel, refactor le. Demandez-vous continuellement "Maintenant, si j'avais commencé à partir de zéro, comment l'aurais-je fait"

Les personnes qui pensent pouvoir concevoir et penser à tout ce qui se passe à l’avant se trompent la plupart du temps, vous (et votre client) apprenez toujours au fur et à mesure. Utilisez ces leçons.

Comme vous êtes un bon programmeur, vous serez capable de refactoriser assez rapidement et comme vous le faites 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 fâchés s’ils savaient que vous "perdiez du temps" à retravailler des choses, il est donc utile de ne pas demander / dire et d’être très rapide à ce sujet.

Le code développé de cette façon vous fera gagner beaucoup de temps et facilitera l’ajout de nouvelles fonctionnalités.

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


1

Miser sur une puissance supérieure

Je ne veux pas dire prier. Je veux dire, assurez-vous qu'il y a un gars d'affaires (c.-à-d. Un chef de projet ou un équivalent) que vous pouvez placer comme bourrage entre vous et le client. Si le client est trop exigeant, laissez le responsable des affaires poser le pied à terre et soyez prêt à utiliser "c'est faisable, mais je ne suis pas sûr que cela rentre dans le champ d'application de la spécification, voir [responsable des entreprises]".

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

De nombreux clients continueront à rechercher des modifications / améliorations / améliorations tant que vous les leur permettrez. Beaucoup abuseront de cette capacité au maximum car cela leur donnera l'impression d'avoir le maximum pour leur argent (même si cela sabote votre projet).

Demandez à une personne de perfectionner et de geler les spécifications dès le début et de les appliquer ultérieurement.

Il n'y a rien de mal à faire un petit extra pour un peu de bon karma avec le client, mais soyez prêt à passer à une puissance supérieure quand ils deviennent incontrôlables. Si la spécification nécessite un nombre ridicule de modifications, il est peut-être temps de revenir en arrière 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 a peu à 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 de votre faute, de sa faute, ou des deux).

Comme d’autres l’ont dit dans de nombreuses réponses, il est également nécessaire d’ajouter un tampon de temps pour les imprévus, mais ce choix doit être décidé à huis clos avant que la spécification ne soit gelée et fournie au client par le PM.


0

Une conception initiale correcte ne peut empêcher le problème. Et il est presque impossible (ou très très difficile) de prendre en compte toutes les exigences futures "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 d’installer une tourelle sur la Ferrari rouge, réexaminez les exigences et construisez un réservoir.


0

Tuez-le avec le feu.

Aka refactor le plus tôt possible: par exemple, quand un code laid vient de se précipiter pour une date limite, je refactais après la date limite car vous ne pouvez pas (ou ne devriez pas au moins) ajouter plus de fonctionnalités jusqu'à ce que le code existant soit maintenable, sinon il sera beaucoup plus difficile de déboguer les codes futurs.


0

Ecrivez des tests unitaires pour vos projets qui testent l'état actuel, puis effectuez une refactorisation lorsque vous en avez le temps. Vous éviterez ainsi de casser votre projet pendant que vous essayez de le nettoyer.


0

Réponse la plus simple. Je cesserais de coder tout type, jusqu'à ce qu'il ait une spécification finale pour exactement ce qu'il / elle veut pour l'instant.

Ensuite, ils doivent donner la priorité à cette liste de fonctionnalités, etc., pour confirmer quels éléments doivent être disponibles à l’heure actuelle, et lesquels peuvent être effectués ultérieurement ....

Utilisez vos expériences pour déterminer le temps et le coût de chaque fonction, puis dites-leur que s’ils le souhaitent, cela prendra x temps et argent.

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

Dites-leur une fois que vous avez une liste finale, que vous apporterez les modifications futures, comme ils préfèrent, mais que vous devez vous concentrer sur les 15/20 premiers qu’ils doivent avoir en ce moment.

Ensuite, en fonction du délai d'achèvement, dites-leur qu'après sa publication, vous serez alors ouvert à la discussion / à la réflexion sur la prochaine version.

Une fois que la 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 a ses idées à l'infini, dites-lui de les noter dans la liste des fonctionnalités de la prochaine version et de vous concentrer sur la fourniture des fonctionnalités les plus importantes qu'ils souhaitent pour le moment.

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

C'est difficile à faire, mais le fluage des fonctions est tellement destructeur de temps, d'énergie, de motivation et de lucidité.


0

Du point de vue du projet complet:

Apprenez du code avec votre équipe, voyez ce qui peut être refactorisé et réutilisé la prochaine fois, puis allez boire 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 tant que toutes les spécifications ne sont pas sur la table et comprises. Ensuite, va boire une bière.

Du point de vue de la planification:

Demandez toutes les spécifications dès le départ et collaborez avec tout le monde pour bien comprendre le chemin du développement. Impliquez le client / les parties prenantes aussi étroitement que possible pour vous assurer que tout le monde est sur la même page. Plus tard dans la nuit, prenez tout le monde bières. Demain, démarrez le projet.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.