L'un des principes de développement logiciel les plus fondamentaux et les plus largement acceptés est le DRY (ne vous répétez pas). Il est également clair que la plupart des projets logiciels nécessitent une forme de gestion.
Maintenant, quelles sont les tâches faciles à gérer (estimation, planification, contrôle)? Exact, tâches répétitives, exactement les tâches à éviter selon DRY.
Donc, du point de vue de la gestion de projet, il est bon de résoudre une tâche en copiant 100 fois du code existant et en apportant des modifications mineures à chaque copie, selon les besoins. A tout moment, vous savez exactement combien de travail vous avez fait et combien il en reste. Tous les gestionnaires vont vous aimer.
Si vous appliquez plutôt le principe DRY et essayez de trouver une abstraction qui élimine plus ou moins le code dupliqué, les choses sont différentes. Habituellement, il y a beaucoup de possibilités, il faut prendre des décisions, faire des recherches, être créatif. Vous pouvez trouver une meilleure solution plus rapidement, mais vous pouvez également échouer. La plupart du temps, vous ne pouvez pas vraiment dire combien de travail il reste. Vous êtes le pire cauchemar d'un chef de projet.
Bien sûr, j'exagère, mais il y a évidemment un dilemme. Mes questions sont les suivantes: quels sont les critères permettant de décider si un développeur a trop à faire sur DRY? Comment pouvons-nous trouver un bon compromis? Ou y a-t-il un moyen de surmonter complètement ce dilemme, pas seulement en trouvant un compromis?
Remarque: cette question est basée sur la même idée que ma précédente, la quantité de travail de routine dans le développement logiciel et son effet sur l'estimation , mais je pense que cela rend mon point plus clair, donc désolé de me répéter :).
la source
Réponses:
Vous semblez présumer que l'objectif principal de la gestion de projet est de produire des estimations exactes. Ce n'est pas le cas. L'objectif principal de la gestion de projet est le même que pour les développeurs: offrir de la valeur au propriétaire du produit.
Un produit utilisant beaucoup de processus manuels lents plutôt que d’automatisation pourrait en théorie être plus facile à estimer (bien que j'en doute), mais il n’apporte pas une optimisation des ressources au client, c’est donc une mauvaise gestion de projet. Il n'y a pas de dilemme.
Il est bien connu que l’estimation de projets logiciels est difficile, de nombreux livres ont été écrits et divers processus ont été développés pour la gérer.
Si le seul objectif du PM était de produire des estimations exactes, ce serait facile. Il suffit de cadrer les estimations à 10X et de laisser les développeurs jouer aux jeux pour le reste s'ils finissent plus tôt. En réalité, cela serait mieux que votre suggestion d'utiliser un copier-coller avec du travail très chargé pour gagner du temps, car les jeux ne réduiront pas la maintenabilité du produit.
Mais en réalité, le responsable du produit souhaite des estimations utiles et un produit de qualité livré le plus rapidement et le moins cher possible. Ce sont les contraintes réelles auxquelles un PM devra faire face.
Dans tous les cas, je conteste votre hypothèse selon laquelle le travail manuel répétitif est plus prévisible que le travail automatisé. Toute l'expérience montre que le travail manuel répétitif est plus sujet aux erreurs. Et si un bogue est découvert dans le code copié-collé? Soudain, le coût de la correction d'un bug est multiplié par le nombre de répétitions, ce qui fait exploser l'incertitude.
la source
Vous avez raison: le copier-coller fonctionne très bien et DRY ne sert à rien si votre tâche est de produire un programme pour lequel le modèle copié ou la copie ne devra plus être conservé ni évolué. Lorsque ces deux composants logiciels ont un cycle de vie complètement différent, les coupler en reformulant le code commun dans une bibliothèque commune, elle-même en cours de développement, peut en effet avoir des effets imprévisibles sur l'effort. En revanche, lors de la copie de sections de code dans un programme ou un système de programme, toutes ces parties auront généralement le même cycle de vie. Je vais illustrer ci-dessous ce que cela signifie pour DRY et la gestion de projet.
Sérieusement, il existe de nombreux programmes de ce type: par exemple, l’industrie du jeu vidéo produit beaucoup de programmes qui doivent être conservés sur une courte période de quelques mois ou un an au maximum, et lorsque ce temps est écoulé, le copier-coller l'ancien code d'un jeu précédent où la période de maintenance est dépassée, la base de code d'un nouveau jeu convient parfaitement et pourrait accélérer les choses.
Malheureusement, le cycle de vie de la plupart des programmes auxquels j'ai eu à faire au cours des dernières années est très différent de cela. 98% des exigences ou demandes de correctifs de bugs qui me sont arrivées étaient des demandes de changementpour les programmes existants. Et chaque fois que vous avez besoin de changer quelque chose dans un logiciel existant, la "gestion de projet" ou la planification donnent de meilleurs résultats lorsque vos efforts de test et de débogage sont assez faibles - ce qui ne sera pas le cas si vous changez quelque chose au même endroit, mais à cause de la copie. une logique métier complexe que vous oubliez facilement que vous devez également modifier une douzaine d'autres emplacements dans la base de code. Et même si vous parvenez à trouver tous ces endroits, le temps de les changer tous (et de tester les changements) est probablement beaucoup plus long, comme si vous n'aviez qu'un endroit à changer. Ainsi, même si vous pouviez faire une estimation précise du changement, le fait d’avoir des coûts douze fois supérieurs au besoin peut facilement entrer en conflit avec le budget du projet.
TLDR - n'hésitez pas à copier si vous développez un programme qui ne nécessite ni responsabilité ni correction de bogues et maintenance de l'original ou de la copie. Mais si vous, votre équipe ou votre entreprise êtes ou pourriez devenir responsables, appliquez DRY chaque fois que vous le pouvez.
Exemple
En tant qu’additif, permettez-moi d’expliquer ce que «correction de bogues et maintenance» signifie, et en quoi cela conduit à une imprévisibilité de la planification, en particulier à l’intérieur d’un produit, par un exemple concret. J'ai effectivement vu ce genre de choses se produire en réalité, probablement pas avec 100 instances, mais les problèmes peuvent même commencer lorsque vous ne disposez que d'une instance en double.
La tâche: créer 100 rapports différents pour une application, chaque rapport ayant un aspect très similaire, certaines différences d’exigences entre les rapports, une logique différente, mais dans l’ensemble, peu de différences.
Le développeur qui obtient cette tâche crée la première (disons que cela prend 3 jours), après quelques modifications ou corrections de bugs mineurs dues au contrôle qualité et à l'inspection du client terminée, il semble fonctionner correctement. Ensuite, il a commencé à créer le prochain rapport en copiant-collant et en modifiant l’ensemble, puis le suivant, et pour chaque nouveau rapport, il a besoin d’environ 1 jour en moyenne. Très prévisible, au premier regard ...
Maintenant, une fois que les 100 rapports sont «prêts», le programme passe en production réelle et certains problèmes surviennent qui ont été négligés au cours de l'assurance qualité. Peut-être y a-t-il des problèmes de performances, peut-être que les rapports se bloquent régulièrement, peut-être que d'autres choses ne fonctionnent pas comme prévu. Maintenant, lorsque le principe DRY aura été appliqué, 90% de ces problèmes pourraient être résolus en modifiant la base de code à un endroit. Mais en raison de l'approche copier-coller, le problème doit être résolu 100 fois au lieu d'une fois. Et en raison des modifications déjà appliquées d'un rapport à un autre, le développeur ne peut pas rapidement copier-coller le correctif du premier rapport sur les 99 autres. Il doit examiner les 100 rapports, les lire, les traduire en modifications. signaler, tester et peut-être déboguer chacun individuellement. Pour le PM, cela commence à devenir très difficile - il peut bien sûr prendre le temps de corriger un bogue "habituel" (3 heures, par exemple) et le multiplier par 100, mais en réalité, il s'agit probablement d'une mauvaise estimation, certaines des corrections pouvant être apportées. plus facile à fabriquer que d’autres, d’autres pourraient être plus difficiles. Et même si cette estimation est correcte, les coûts de débogage 100 fois supérieurs à ceux qu’ils auraient dû coûteront très cher à votre entreprise.
La même chose se produira la prochaine fois que le client demandera de changer la couleur de l'emblème de sa société dans tous ces rapports, de rendre la taille de la page configurable ou d'une autre nouvelle exigence qui affecte tous les rapports de la même manière. Donc, si cela se produit, vous pouvez faire une estimation des coûts et facturer au client 100 fois le prix qu’il devrait payer lorsque le code était DRY. Cependant, essayez ceci plusieurs fois et le client annulera le projet car il ne sera probablement pas disposé à payer vos coûts d'évolution exorbitants. Et peut-être qu'à ce moment-là quelqu'un posera la question pourquoi cela est arrivé et montrera du doigt la personne qui a pris la décision pour cette programmation en copier-coller.
Mon point est le suivant: lorsque vous produisez un logiciel pour d’autres personnes, vous avez toujours au moins pour une courte période la responsabilité de faire fonctionner la chose, de corriger les bugs, d’adapter le programme à des exigences changeantes, etc. Même dans un projet en vert, les pièces peuvent rapidement s’ajouter à l’effort de développement initialement prévu. Et surtout lorsque tout votre code copié-collé est contenu dans un même produit, la période de responsabilité est la même pour toutes les parties, ce qui est très différent de la situation où vous copiez-collez du code plus ancien provenant d'un projet mort qui n'est plus. en maintenance active.
la source
Votre assertion de base est incorrecte.
Ce qui différencie les logiciels des autres professions, c'est que vous créez quelque chose de nouveau chaque jour. Après tout, aucun client ne va vous payer pour construire quelque chose que quelqu'un d'autre a déjà fait. Les gestionnaires de projet aiment peut-être la prévisibilité, mais leurs chefs aiment la valeur . Si vous ne faites que copier-coller du code avec de légères variations, vous n'apportez pas beaucoup de valeur à l'entreprise.
Finalement, la société réalisera qu’elle peut faire le même travail en une fraction du temps en embauchant un bon programmeur. Et s'ils ne le font pas, leurs concurrents le feront.
la source
La programmation par copier-coller mène éventuellement à un logiciel abandonné. J'étais sous-traitant d'un système de commande de services filaires auprès d'une très grande compagnie de téléphone. Le système a été coupé-collé ad nauseum parce que tous les tests étaient manuels et ils ne voulaient pas changer de code fonctionnel. La moindre amélioration pourrait permettre de créer une nouvelle copie de centaines de lignes de code. À l'origine, l'application était conçue pour gérer des comptes comportant jusqu'à douze lignes physiques. Bien sûr, cette limitation a été faite dans des centaines d'emplacements dans le code. Après environ quatre ans d'activité, les entreprises ont demandé à l'équipe ce qu'il faudrait faire pour gérer des comptes plus importants. Ils ont estimé environ 18 millions de dollars. À ce stade, le projet a été confié à une équipe offshore pour une maintenance minimale. L'équipe existante a été mise à pied.
Les organisations qui pensent de cette manière se font écraser par des entreprises dotées d'une meilleure technologie.
la source
Une règle souvent oubliée et applicable ici est la règle de 3 . Cela indique qu'il est correct de copier le code une fois, mais au-delà, il devrait être remplacé par du code générique.
3 peut sembler un nombre arbitraire, mais un scénario courant est celui où les données et la logique sont dupliquées dans une application et une base de données. Un exemple souvent cité est celui où il y a une table de recherche dans la base de données et un côté client d'énumération. La différence de paradigmes ne permet pas de stocker facilement ces informations dans un seul endroit, de sorte que les informations apparaissent souvent aux deux endroits.
Bien qu'il soit agréable d'avoir du code DRY, il peut arriver que la logique métier dicte une exception et vous devez donc créer deux bits de code ou plus à partir d'une source qui était générique auparavant.
Alors que faire? Code pour le statu quo (après tout, YAGNI ). Alors que le code devrait être écrit pour faciliter les modifications, écrire tout un tas de cloches et de sifflets pour quelque chose qui pourrait ne pas être nécessaire revient à brûler de l'argent.
la source
Dans votre question, vous ne citez que trois fonctions de la gestion de projet: estimation, planification et contrôle. La gestion de projet consiste à atteindre des objectifs dans les limites du projet. Les méthodes utilisées pour atteindre les objectifs dans les limites d'un projet sont différentes des projets logiciels par rapport à de nombreux autres types de projets. Par exemple, vous souhaitez que les processus de fabrication soient hautement reproductibles et bien compris. Cependant, le développement logiciel est principalement un travail de connaissance- Il s'agit d'une procédure inhabituelle qui nécessite de réfléchir plutôt que de suivre des instructions et des procédures rigides. Les techniques utilisées pour initier, planifier, exécuter, surveiller et contrôler et fermer un projet logiciel vont devoir prendre en compte le type de travail à effectuer sur un projet logiciel - en particulier, les travaux non routiniers impossibles à effectuer. aux instructions et procédures spécifiques.
Je pense que l’autre problème est que vous utilisez DRY, un concept qui se rapporte à la répétition de l’information, et que vous essayez de l’appliquer à la gestion des tâches. DRY dit simplement que vous ne devriez avoir qu'une seule représentation des informations faisant autorité. Les chefs de projet devraient accepter cela, car cela signifie que tout le monde saura où aller pour obtenir l'information, communiquer les changements sera facile et les changements pourront être contrôlés et gérés correctement. DRY, grâce à des éléments réutilisables, contribue à réduire les coûts à long terme, à maintenir les calendriers à long terme et à améliorer la qualité - trois éléments du triangle de la gestion de projet . Il faut investir un peu de temps et d’argent pour que les choses soient réellement sèches, mais le chef de projet doit faire des compromis en termes de temps, de coût, de calendrier et de qualité.
la source
L'écriture de nouveau code n'est qu'une petite partie de la tâche
Votre suggestion faciliterait l'estimation de la part d'écriture initiale du nouveau code. Cependant, pour apporter quoi que ce soit de nouveau (peu importe qu'il s'agisse d'un tout nouveau système, d'un ajout de fonctionnalité ou d'un changement de fonctionnalité), cela ne suffit pas, ce n'est qu'une minorité de travail - les estimations observées dans la littérature indiquent qu'en pratique une partie représente environ 20% à 40% du travail total.
Par conséquent, la majorité du travail (y compris l’adaptation de votre développement initial aux besoins réels, l’intégration, les tests, la réécriture, le re-test) n’est pas plus facile à estimer; Inversement, éviter intentionnellement DRY a simplement rendu cette partie beaucoup plus grande, plus dure et avec des estimations plus variables - ce bogue ou ce besoin de changement qui nécessite de modifier toutes les parties clonées peut ne pas se produire, mais si tel est le cas, vos estimations vont être totalement faux.
Vous n'obtenez pas de meilleures estimations en améliorant la qualité de vos estimations pour une petite partie du travail mais en l'aggravant pour une grande partie du travail. il ne s'agit donc pas vraiment d'un compromis, mais d'une situation de perte à perte dans laquelle vous obtenez une productivité et des estimations de moins en moins bonnes.
la source
DRY est utile mais il est aussi surestimé. Certaines personnes peuvent aller trop loin. Ce que de nombreux développeurs ne réalisent pas, c’est que chaque fois que vous implémentez DRY pour utiliser la même méthode à deux fins (légèrement) différentes, vous introduisez une sorte de couplage très étroit entre les différentes utilisations. Maintenant, chaque fois que vous modifiez le code pour le premier cas d'utilisation, vous devez également vérifier s'il régresse le deuxième cas d'utilisation. S'il s'agit de cas d'utilisation largement indépendants, il est très difficile de savoir s'ils doivent être étroitement couplés - ce ne devrait probablement pas être le cas.
Une surutilisation de DRY peut également conduire à des méthodes divines dont la complexité explosive pour traiter tous les cas d'utilisation auxquels elles sont soumises, alors que des méthodes atomiques généralement plus petites qui répliquent du code seraient beaucoup plus faciles à gérer.
Cependant, je suggérerais que la question ne soit pas vraiment pertinente au niveau de la gestion de projet. Un chef de projet ne veut vraiment pas se préoccuper de ce niveau de détail de mise en œuvre. S'ils le sont, c'est probablement la micro-gestion. Vraiment ... la façon dont les choses sont mises en œuvre relève davantage de la responsabilité du développeur et du responsable technique. La gestion de projet est plus préoccupée par ce qui est fait et quand .
EDIT: par commentaire, je suis cependant d’accord pour dire que, dans la mesure où il est plus facile d’ estimer le temps de développement, éviter DRY peut parfois réduire l’incertitude. Mais j'estime qu'il s'agit d'une question insignifiante en ce qui concerne les questions plus pressantes suivantes: (1) combien de temps faudra-t-il pour que les exigences commerciales soient satisfaites, (2) quelle dette technique est prise en compte dans le processus, et (3) le risque lié au coût total de l'appropriation des choix architecturaux effectués - le fait de choisir ou non de sécheresse dans de nombreux cas est un choix de conception qui devrait être davantage basé sur le risque / rendement de ces facteurs que sur la possibilité de fournir un peu plus facilement des informations plus précises aux chefs de projet .
la source
Je pense que vous comprenez mal DRY.
Prenons un exemple:
contre.
En remplaçant la classe B par C, nous avons suivi le principe DRY et réduit la duplication de code. Mais nous n'avons pas augmenté les inconnues ou les risques pour le projet (à moins que vous n'ayez jamais fait un héritage auparavant).
Je pense que ce que vous voulez dire quand vous parlez de DRY ressemble plus à une tâche de conception. C'est à dire:
!!! Nouvelle exigence! Certains clients doivent pouvoir multiplier les doubles !!
contre.
Ici (en supposant que cela fonctionne), nous avons conçu une solution qui peut traiter à la fois de l’ancien ET de la nouvelle exigence, en essayant essentiellement de créer un modèle mathématique du problème réel ou des règles de gestion. Dans la réalité, le système que nous modélisons sera évidemment beaucoup plus compliqué, notre modèle ne s’adaptera pas exactement, et les cas extrêmes et les résultats inattendus prendront du temps à trouver et à corriger.
Alors, devrions-nous prendre B ou A version 2 dans ce cas?
B sera plus spécifique au changement demandé avec moins d’effets secondaires, plus facile à estimer et plus rapide.
Une version 2 réduira le code global et constituera la solution la plus élégante.
Encore une fois, je dirai que cela dépend de la qualité des spécifications et des exigences.
Si nous avons des spécifications très claires qui couvrent les cas extrêmes et la compatibilité ascendante, nous pouvons alors être sûrs de comprendre le système suffisamment bien pour refactoriser le modèle sans générer de bugs.
Si nous avons une demande d'urgence pour un client unique, la seule exigence étant que le comportement de ce client change sans tenir compte du système global; puis «améliorer» le modèle en refacturant A, le risque est considérable. Que ce soit pour casser d'autres clients ou dépasser le délai imparti en raison du temps supplémentaire indéterminé nécessaire pour concevoir et tester la solution.
la source
Paragraphe par paragraphe
Correct.
Les tâches répétitives doivent être automatisées, obligatoires . Ils sont ennuyeux, sujets aux erreurs, quand ils sont faits à la main.
Je pense que vous pouvez changer le mot "adaptation" avec "configuration". Considérez que vous avez un bogue dans ce morceau de code censé être copié. Un bug qui apparaît sous des conditions spécifiques. S'il n'est pas corrigé dans la source d'origine et copié, il y aura beaucoup d'endroits à réparer. Cela peut être mauvais, mais alors quelqu'un doit:
L'élimination des duplications conduit à un point d'échec unique. Si quelque chose échoue, vous pouvez être sûr de savoir où cela se produit. SOLID et Design Patterns sont là pour vous aider à résoudre exactement ce problème. Des délais trop courts ont tendance à provoquer un "codage" de style procédural. Plus de temps investi dans un projet afin de créer quelque chose de réutilisable signifie que la fonctionnalité sera réutilisée au cours du prochain projet, mais elle devrait être configurable en premier lieu.
Beaucoup de gens ont souligné qu'il n'y avait pas de dilemme ici. Oui et non.
Si vous avez quelque chose de très expérimental qui n'a jamais été réalisé auparavant, il n'y a pas de dilemme. Sinon, si vous avez quelque chose à refaire, comme le nouveau système de réservation, vous avez déjà des abstractions, cela dépend de ce dont vous avez besoin.
Je pense que le dilemme est le suivant: devrions-nous implémenter quelque chose dans une fonctionnalité s'il est peu probable qu'il soit demandé? Mettre en œuvre quelque chose lorsque demandé. Personne n'a besoin d'une infrastructure énorme qui ne sera pas utilisée.
la source
Il est absolument question de design. Peut - être pas une réutilisation en soi, mais un design quand même.
Expérience et votre environnement / situation existant. Pour un problème donné, vous obtiendrez un sens fort du principe du Prado en essayant des degrés de sécheresse plus importants. Soudain, des considérations de gestion entrent en ligne de compte. Le temps, les objectifs, le client, la gestion de code à long terme (quelqu'un a une dette technique ), etc., informeront votre plan d’attaque.
Euh ... design? La refactorisation, c'est du design, c'est supposé l'être. La portée du DRYing peut facilement s’étendre comme une super nova de la boucle, à la méthode, aux classes. Été là, fait ça. Mais vous ne pouvez pas vraiment savoir avant d’étudier le problème - c’est le design.
Comment ne peut-il pas s'agir d'un problème de conception? Vous devez considérer le problème plus largement que le code dupliqué immédiat sous la main. Il s’agit d’une activité de conception, que ce soit du code existant ou une feuille vierge; qu'il s'agisse d'une "méthode d'extraction" ou de la création de nouvelles classes et de nouveaux modules.
Épilogue
Gestion typique, en ignorant le temps de conception. Nous aurions idéalement conçu la répétition superflue avant le codage. Au lieu de cela, la direction pense que le développement (et les corrections de bugs) est un événement olympique unique - le codage - alors qu’il s’agit d’un décathlon. Et ils mesurent à 1/1000 de seconde parce qu'ils pensent que tout est analogique.
J'ai eu cette expérience: "J'ai passé deux jours à écrire cette ligne (d'un formulaire GUI) et deux heures à écrire le reste du formulaire." Je veux dire que j’ai pris le temps d’identifier les classes réutilisables (DRY étant un effet secondaire naturel), la rangée de formulaires de l’interface graphique et certaines autres. Une fois débogués, ceux-ci étaient utilisés, individuellement et en composition, dans l'ensemble du formulaire, qui codait maintenant très rapidement et dont les tests étaient exceptionnellement rapides, en dépit de la complexité croissante. Et il a également volé à travers des tests formels avec un taux de bugs incroyablement bas.
Je ne le savais pas non plus, mais je croyais que l'effort de conception initial porterait ses fruits. Nous disons tous cela, mais la direction en particulier ne lui fait pas confiance. La direction aurait pu penser que je déconnais. "Deux jours et vous n'avez même pas encore 2% de code codé!"
Dans un cas, nous sommes restés fidèles à nos armes lorsque la direction a déclaré "vous passez trop de temps à la conception, allez-y." Et des collègues qui disent "c'est trop de classes". Eh bien, un sous-projet beaucoup moins complexe était censé durer environ un mois (je pensais que c’était acceptable) mais a pris cinq mois. 3 mois de ce temps étaient en test / réparation car c’était un tel point de vente. "Mais nous n'avons pas eu le temps de concevoir!". Ils ont effectivement dit cela.
Montrer à la direction comment ça marche. Capturer des données. Comparez avec d'autres travaux, en particulier celui de vos collègues de travail qui font le travail pressé slap-dash. Cette pile d'échecs semble toujours perdre la course, rester coincée dans les tests et, après la publication, revenir encore et encore pour corriger plus de bugs.
la source