DRY est-il l'ennemi de la gestion de projet logiciel?


83

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 :).


96
Dites-nous comment vos équipes de gestion de projet se sentent au moment de rechercher, de modifier et de tester quelque chose dans les 100 instances de ce type copiées-collées. Et n'oubliez pas le temps supplémentaire que vous passerez à trouver pourquoi il est cassé car seulement 98 d'entre eux ont été changés.
Blrfl

16
@Blrfl, d'un autre côté, prématurément sécher du code avant qu'une bonne abstraction ne soit claire peut réellement nuire à la productivité, car une abstraction partagée est une dépendance partagée. En fait, je ne suis pas en désaccord, mais je tiens à souligner qu'il faut trouver un équilibre.
GoatInTheMachine

16
Le principe qui empêche DRY de devenir incontrôlable est le principe YAGNI (vous n'en aurez pas besoin) .
Philipp

88
Il n'y a pas de dilemme. Si le chef de projet souhaite que vous fassiez beaucoup de travail manuel superflu, car il est facile à estimer, la solution évidente est de renvoyer le chef de projet.
JacquesB

10
Si vous vous répétez, il vous reste tout de même à faire tout ce travail difficile à estimer , plus un travail supplémentaire inutile. Alors, comment cela aide-t-il le projet?
user253751

Réponses:


134

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.


21
Je suis tout à fait d’accord avec vos affirmations, mais je pense qu’il convient de noter qu’il existe de nombreux chefs de projets moche qui préfèrent vraiment la prévisibilité à la rapidité ou à la qualité. La plupart des gens qui n'ont aucune formation en gestion de projet apprennent ce qu'ils savent à partir de ce qu'ils ont vu. Mon expérience est que les gestionnaires de projet qui peuvent gérer l'incertitude de manière calme et rationnelle sont rares.
JimmyJames

5
@FrankPuffer J'y suis allé. Combien de temps cela prendra-t-il? Une option ici est de fournir une gamme. Renseignez-vous sur PERT en particulier sur les estimations à 3 points, car ils devraient déjà être au courant. Pourcentage terminé? C'est le plus énervant. Essayez de l'ignorer, mais si vous ne vous en souvenez pas, il s'agit du pourcentage de temps, pas du pourcentage de lignes codées. Ce qu'ils veulent vraiment savoir, c'est quand sera-t-il terminé? Dès le début, donnez des prévisions prudentes pour chaque tâche et affinez-les au fur et à mesure. Attendre la dernière minute pour vous dire plus de temps rendra les gens fous.
JimmyJames

11
Combien de temps cela prendra-t-il? Je suis sûr à 60% que nous pouvons le terminer par x, mais il y a 10% de chances que cela prenne cinq fois plus longtemps.
David

18
@David: Cela rendrait probablement le premier ministre fou parce qu'il sait d'expérience que ces 10% de chances se produisent 80% des fois :)
Frank Puffer

7
La réalité est que de nombreux endroits aimeraient suivre un projet sur le terrain, puis réussir inopinément. Les PM sont souvent récompensés pour leurs projections précises et leurs incitations perverses. C'est le problème principal-agent .
Traîneau

39

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.


4
Probablement une bonne réponse mais beaucoup trop verbeuse comparée à d'autres bonnes réponses.
Vince O'Sullivan

4
Vous pouvez ignorer DRY lorsque "la copie ne devra pas être conservée ou évoluée dans le futur", mais le code qui ne sera plus jamais utilisé finit souvent par être réutilisé de toute façon.
Andy Lester

"copier-coller fonctionne très bien ..." - pas d'accord! Même si le programme est unique et garanti de ne jamais évoluer au-delà de la version initiale, le code copier-coller rend le travail beaucoup plus laborieux et plus risqué de corriger les bugs détectés lors du développement de la version initiale du programme. À moins que vous ne commettiez jamais d'erreur, auquel cas vous êtes un Dieu.
JacquesB

1
@JacquesB: vous devriez lire ma réponse plus attentivement, je n'ai pas écrit quelque chose de différent.
Doc Brown

La programmation informatique est juste différente de la construction de machines identiques avec une chaîne de montage. Huh. Qui l'aurait cru? Peut-être devrions-nous avoir des programmeurs travaillant en tant que chefs de projet. Mais nous aurions alors besoin de programmeurs en tant que gestionnaires. Les programmeurs en tant qu'actionnaires. Les programmeurs en tant que clients ... Shoot, apprenez simplement à tout le monde à programmer et à vous en servir. (En d'autres termes: les non-experts ne comprendront jamais les vicissitudes connues des experts.)

19

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.

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.


2
Je dirais que la plupart des professions d'ingénierie consistent à "créer quelque chose de nouveau chaque jour"
BlueRaja - Danny Pflughoeft

12
@ BlueRaja-DannyPflughoeft: Pas vraiment. En tant qu'ingénieur électronicien / électricien, je peux témoigner que la plupart des grandes entreprises d'ingénierie (les projets nécessitant une mise en service, comme la construction de navires et les centrales électriques), consistent à s'assurer que les personnes qui font des essais et des tests le font correctement. C'est ce que les entreprises considèrent comme "ingénierie". Faire de la nouveauté, c'est "R & D"
slebetman

3
@slebetman Peut-être que vous n'avez simplement pas remarqué tout le travail que faisait votre direction; même lorsque vous faites la même chose encore et encore, l'environnement change à chaque fois: vous n'avez pas de modèle de centrale que vous pouvez simplement livrer à un client et vous en avez fini avec ce travail, vous devez effectuer des levés, déterminez comment approvisionner l'usine en matières premières et rapportez le produit, gérez toutes les matières premières pour la construction et résolvez les problèmes d'approvisionnement, de pénurie de travail et d'un million d'autres choses. Cela ressemble à du travail sur des modèles (comme le font de nombreux logiciels), mais ce n’est vraiment pas le cas.
Luaan

1
@ Luan: Oui, mais rien de tout cela ne crée quelque chose de nouveau. Tous font "quelque chose que nous savons faire". Le développement logiciel est différent. Principalement parce que dans le logiciel, contrairement aux projets d'ingénierie physique, nous avons tendance à encapsuler ce que nous savons déjà faire dans les bibliothèques, de sorte que nous n'ayons pas à "effectuer l'arpentage" manuellement, etc. Nous voudrions simplement importer une bibliothèque pour cela et l'utiliser. .
Slebetman

2
@slebetman Presque tous les logiciels en cours d'écriture sont "quelque chose que nous savons faire". Les bibliothèques vivent également dans un environnement en constante évolution. Et vous ne possédez pas une connaissance et une expérience à 100% de l'ensemble de la bibliothèque, de toutes les dépendances de cette bibliothèque et des autres dépendances que vous possédez, et il existe de nombreuses configurations de systèmes et de matériels étranges qui refusent simplement de fonctionner comme un système raisonnable travail. L’encapsulation est excellente, mais c’est quand même très chère et qu’elle nécessite des tonnes d’enquêtes. Et l’ingénierie a aussi l’encapsulation - blocs préfabriqués, circuits intégrés, etc.
Luaan

12

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.


Il pense que c'est un meilleur cerveau, plutôt qu'une meilleure technologie. La technologie vient du cerveau, non? Qu'est-ce qui est arrivé à "Pense plus intelligent, pas plus difficile"?

10

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.


6
Notez que cela signifie que vous devez indiquer que vous avez copié le code (aux deux endroits) afin de savoir si vous êtes sur le point de le copier à nouveau, vous ne devriez pas!
Mark Hurd

3
J'ai fait cela dans un cas où deux classes avaient besoin de la même méthode mais étaient à peine apparentées - un peu comme des cousins ​​éloignés. J'aurais dû ajouter des dépendances à près d'une douzaine de classes pour qu'elles partagent le code. J'ai donc aimé ce que Mark a suggéré - copier-coller la méthode et également laisser un commentaire important et évident qui indiquait l'autre emplacement de cette méthode.
Jeutnarg

@MarkHurd Yep - excellent point ...
Robbie Dee

8

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é.


Bien sûr, le développement de logiciels est un travail de connaissance. En fait, je ne considérerais même pas mon premier exemple (copier / coller) comme un développement logiciel au sens strict. Néanmoins, la gestion de ce type de travail est beaucoup plus difficile, de sorte que le premier ministre, même s’il a une formation en développement et sait tout cela, sait que, dans son rôle de premier ministre, il a tendance à l’ignorer. (Je ne dis pas que c'est une bonne chose, c'est juste ce que j'ai observé à de nombreuses reprises. Je ne pense pas non plus que ces PM soient stupides ou incompétents. C'est plutôt comme le rôle qui les oblige parfois à agir de la sorte. )
Frank Puffer

3
@FrankPuffer Je ne suis pas d'accord sur le fait que le rôle de gestionnaire de projet force la personne à prendre des décisions particulières. C'est plus probablement une force éducative ou organisationnelle. D'après ce que j'ai vu, la plupart des formations en gestion de projet se concentrent sur des techniques de gestion de projet plus traditionnelles (probablement parce qu'elles s'appliquent plus communément à davantage de projets) que sur des techniques de gestion de projet par logiciel. Cela peut se répercuter sur les organisations qui s’y attendent et n’examinent pas d’autres techniques de gestion de projets de travail axés sur le savoir, comme le développement de logiciels.
Thomas Owens

2
@FrankPuffer Bien sûr, c'est plus difficile, mais cela apporte plus de valeur. Si le patron de votre supérieur hiérarchique est assez intelligent, il se débarrassera du responsable qui tente de "se faciliter la tâche" et trouvera une personne capable de faire son travail. Ne vous méprenez pas, si faciliter les choses crée de la valeur, allez-y - mais dans ce que vous décrivez, c'est presque certainement au détriment de la valeur finale.
Luaan

4

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.


C'est un bon point. Cependant, DRY ou des principes similaires s'appliquent également à d'autres tâches telles que les tests ou l'intégration. La plupart des choses peuvent être faites de manière mécanique, sans trop réfléchir ou de manière plus intelligente. Les solutions intelligentes sont souvent beaucoup plus rapides mais comportent un risque d'échec. De plus, vous devez y mettre beaucoup de travail avant d’obtenir un résultat.
Frank Puffer

Il n'y a pas de "risque d'échec", il y a une certitude d'échec. Tout échouera tôt ou tard. Vous choisissez simplement le coût du corbillard et la vitesse à laquelle vous conduisez.

4

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 .


Bien entendu, le chef de projet ne doit pas s'occuper des détails de la mise en œuvre. Ce n'est pas mon propos. Mon point est que, selon la façon dont un développeur implémente quelque chose, il est plus ou moins capable de fournir les informations nécessaires à la gestion de projet.
Frank Puffer

Cela n’a aucun sens pour moi d’endommager / de contraindre le produit ou de créer une dette technique simplement pour pouvoir mieux en rendre compte. La valeur du rapport doit sûrement être inférieure d'un ordre de grandeur à la valeur d'un travail de qualité. Mais YMMV
Brad Thomas

Peut-être que les programmeurs devraient être payés des ordres de grandeur plus que les gestionnaires?

2

Je pense que vous comprenez mal DRY.

Prenons un exemple:

public Class A
{
    public int Multiply(int x, int y)
    {
        return x * y;
    }
}

public Class B
{
    public int Multiply(int x, int y)
    {
        return x * y;
    }

    public int Add(int x, int y)
    {
        return x + y;
    }
}

contre.

public Class C : A
{
    public int Add(int x, int y)
    {
        return x + y;
    }
}

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:

public Class A
{
    public int Multiply(int x, int y)
    {
        return x * y;
    }
}

!!! Nouvelle exigence! Certains clients doivent pouvoir multiplier les doubles !!

// Use class B for new clients!!
public Class B
{
    public int Multiply(double x, double y)
    {
        return x * y;
    }
}

contre.

public Class A // Version 2
{
    public int Multiply(int x, int y)
    {
        return Multiply(x as double, y as double);
    }

    public int Multiply(double x, double y)
    {
        return x * y;
    }
}

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.


7
Je ne suis pas d'accord L'héritage n'est pas quelque chose que vous faites une fois pour ensuite le maîtriser. Il y a beaucoup de pièges. Il y a des raisons pour lesquelles la composition devrait être préférée à l'héritage. Nous devons donc prendre une décision: héritage? Composition? Autre chose? Cette décision sera probablement difficile dans le monde réel. Dans le deuxième exemple, il y a aussi beaucoup d'alternatives. Qu'en est-il des génériques / modèles? Peut-être une approche fonctionnelle utilisant des lambdas? Encore une fois: beaucoup de possibilités dont chacune aura des implications spécifiques.
Frank Puffer

4
Dans le premier exemple, vous supprimez littéralement le code en double, quelle que soit la méthode utilisée. mais le même code est exécuté dans les deux sens. Il n'y a donc aucun changement de fonctionnalité. Dans le deuxième exemple, vous modifiez l'approche en une chose qui, espérons-vous, est fonctionnellement identique mais qui est en réalité un code différent
Ewan

1
J'étais dans une situation où votre "demande d'urgence" était la norme. La société pour laquelle j'ai travaillé a créé des systèmes de données personnalisés pour de nombreux clients. Au début, ils ont créé un système avec Cobol, puis l'ont copié pour le prochain client, etc., jusqu'à ce qu'ils aient 100 clients. Maintenant, ils avaient un travail à faire pour essayer d'apporter des améliorations et des mises à jour systématiques. Je travaillais sur un système capable de reproduire le comportement de la plupart de ces systèmes, en utilisant un seul ensemble de code source, mais les personnalisations stockées dans les données de configuration. Nous ne pouvions pas tout faire et certaines choses ne pouvaient pas être ajoutées.

1

Paragraphe par paragraphe

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.

Correct.

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.

Les tâches répétitives doivent être automatisées, obligatoires . Ils sont ennuyeux, sujets aux erreurs, quand ils sont faits à la main.

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.

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:

  • corrigez d'abord le code dans la source d'origine;
  • corrigez le code dans tous les autres endroits;
  • assurez-vous que ce sont tous les lieux. Lorsque vous dites que cela devait être fait au responsable, il détestera probablement au moins quelqu'un.

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. Généralement, 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.

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.

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?

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.


Mettre en œuvre quelque chose de la manière simple et rapide maintenant, parce que cela a été demandé. Plus tard, lorsque des moyens complexes sont nécessaires, l’effort initial ne sert à rien, il faut tout recommencer. Le gestionnaire n'aime pas cela. Comme si vous disiez: "Le temps passé à conduire vers l'ouest était inutile si maintenant nous devons aller vers l'est." Mais faire le tour du monde la première fois pour pouvoir aller dans l’est tout au long de la route est également une perte de temps.

1

il ne s'agit pas du tout de concevoir pour une réutilisation future ou du principe de YAGNI. Il s'agit de répéter le code dans le package de travail actuel.

Il est absolument question de design. Peut - être pas une réutilisation en soi, mais un design quand même.

Quels sont les critères pour décider si un développeur a trop à faire sur DRY?

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.

Comment pouvons-nous trouver un bon compromis?

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

... la question posée et ses réponses ne couvrent pas l'aspect gestion de projet.

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.

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.

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.

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.

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.

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?

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.


"Mesurer avec un micromètre, marquer à la craie, couper avec une hache."
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.