Je suis sûr qu'il y a un nom pour cet anti-modèle quelque part; cependant je ne connais pas assez la littérature anti-modèle pour la connaître.
Considérez le scénario suivant:
or0
est une fonction membre d'une classe. Pour le meilleur ou pour le pire, cela dépend fortement des variables des membres de la classe. Le programmeur A vient et a besoin de fonctionnalités comme or0
mais plutôt que d'appeler or0
, le programmeur A copie et renomme toute la classe. Je suppose qu'elle n'appelle pas or0
parce que, comme je l'ai dit, cela dépend fortement des variables membres pour sa fonctionnalité. Ou peut-être qu'elle est programmeur junior et ne sait pas comment l'appeler à partir d'un autre code. Alors maintenant, nous avons or0
et c0
(c pour copie). Je ne peux pas blâmer complètement le programmeur A pour cette approche - nous respectons tous des délais serrés et nous piratons le code pour faire le travail.
Plusieurs programmeurs maintiennent or0
donc c'est maintenant la version orN
. c0
est maintenant une version cN
. Malheureusement, la plupart des programmeurs qui ont maintenu la classe contenant or0
semblaient ignorer complètement c0
- ce qui est l'un des arguments les plus forts auxquels je puisse penser pour la sagesse du principe DRY. Et il peut également y avoir eu une maintenance indépendante du code dans c
. De toute façon, il semble que or0
et c0
ont été maintenus indépendants les uns des autres. Et, joie et bonheur, une erreur se produit cN
qui ne se produit pas orN
.
J'ai donc quelques questions:
1.) Y a-t-il un nom pour cet anti-modèle? J'ai vu cela se produire si souvent que j'aurais du mal à croire que ce n'est pas un anti-modèle nommé.
2.) Je peux voir quelques alternatives:
a.) Correction orN
pour prendre un paramètre qui spécifie les valeurs de toutes les variables membres dont il a besoin. Modifiez ensuite cN
pour appeler orN
avec tous les paramètres nécessaires transmis.
b.) Essayez de porter manuellement les correctifs de orN
à cN
. (Attention, je ne veux pas faire ça mais c'est une possibilité réaliste.)
c.) Recopiez orN
à - encore une cN
fois, beurk mais je l'énumère par souci d'exhaustivité.
d.) Essayez de comprendre où cN
est cassé puis réparez-le indépendamment de orN
.
L'alternative a semble être la meilleure solution à long terme, mais je doute que le client me laisse la mettre en œuvre. Jamais de temps ou d'argent pour réparer les choses mais toujours du temps et de l'argent pour réparer le même problème 40 ou 50 fois, non?
Quelqu'un peut-il suggérer d'autres approches que je n'ai peut-être pas envisagées?
la source
Réponses:
c'est juste appelé du code en double - je ne connais plus de noms fantaisistes pour cela. Les conséquences à long terme sont, comme vous l'avez décrit, pires.
Bien sûr, l'élimination de la duplication est l'option idéale si seulement possible. Cela peut prendre beaucoup de temps (dans un cas récent de notre projet hérité, j'avais plusieurs méthodes dupliquées dans plus de 20 sous-classes dans une hiérarchie de classes, dont beaucoup avaient évolutivement développé leurs propres différences / extensions au fil des ans. Cela a pris environ 1,5 an à travers des tests unitaires successifs et une refactorisation pour me débarrasser de toutes les duplications. La persévérance en valait la peine).
Dans un tel cas, vous pouvez toujours avoir besoin d'une ou plusieurs des autres options en tant que correctifs temporaires, même si vous décidez de commencer à éliminer la duplication. Cependant, lequel de ceux-ci est le meilleur dépend de nombreux facteurs, et sans plus de contexte, nous ne faisons que deviner.
De nombreuses petites améliorations peuvent faire une grande différence à long terme. Vous n'avez pas non plus nécessairement besoin de l'approbation explicite du client pour ces derniers - un petit refactoring à chaque fois que vous touchez ladite classe pour corriger un bogue ou implémenter une fonctionnalité peut aller très loin dans le temps. Incluez simplement du temps supplémentaire pour la refactorisation dans vos estimations de tâches. C'est comme la maintenance standard pour maintenir le logiciel en bonne santé à long terme.
la source
Il y a une référence au modèle WET (We Enjoy Typing) mais je ne sais pas s'il s'agit d'un nom standard.
la source
Si je vous comprends bien, il se passe trop de choses en classe. Cela crée des méthodes qui ne suivent pas le principe de la responsabilité unique . Menant à du code qui doit être déplacé, des morceaux pris tandis que d'autres sont laissés de côté. Cela pourrait également créer beaucoup de membres.
Vous devez également consulter les modificateurs d'accessibilité. Assurez-vous que les choses qui sont publiques devraient en fait être publiques. Le consommateur n'a pas besoin de connaître chaque petit membre ... utilisez l'encapsulation.
Cela nécessite un refactor. Il semble également que le code soit écrit sans conception initiale. Regardez dans le développement piloté par les tests. Écrivez le code comme il doit être appelé plutôt que d'appeler du code, quelle que soit sa mise en œuvre. Regardez dans TDD pour quelques conseils sur la façon d'accomplir la tâche.
la source
Si vous copiez du code, vous introduirez une dette technique de double maintenance ou plus précisément: la duplication de code .
Habituellement, cela est résolu par une refactorisation. Plus précisément, vous redirigez tous les appels vers une nouvelle fonction (ou une nouvelle méthode dans une nouvelle classe) qui a le code commun. La façon la plus simple de commencer est de supprimer tout le code copié et de voir ce qui se casse, dans lequel vous corrigez en redirigeant les appels vers le code commun.
Faire en sorte que votre client accepte de refactoriser le code peut être difficile car il est difficile de convaincre une personne non technique de régler une dette technique. Donc, la prochaine fois que vous donnerez des estimations de temps, incluez simplement le temps nécessaire pour refactoriser vos estimations . La plupart du temps, les clients supposent que vous nettoyez le code pendant que vous effectuez la correction.
la source
Cela ressemble à du code de spaghetti pour moi. La meilleure solution est une refonte / réécriture.
la source
Vous dites que vous ne pouvez pas blâmer complètement A - mais copier une classe de cette façon est en fait impardonnable. C'est un échec massif dans votre processus de révision de code. C'est peut-être l'échec le plus massif, n'ayant aucune révision de code.
Si jamais vous pensez que vous devez produire un code affreux pour respecter une date limite, alors la demande de priorité absolue la plus élevée pour la publication devrait être de corriger le code affreux MAINTENANT. Votre problème a donc disparu.
Le principe DRY est destiné aux situations qui ne sont pas tout à fait parfaites et peuvent être améliorées. Dupliquer une classe est un tout nouveau calibre. Je l'appellerais d'abord «code dupliqué», et avec le temps, il deviendra le pire de tous les temps, «code dupliqué divergent»: plusieurs copies du même code qui sont presque, mais pas tout à fait identiques, et personne ne sait si les différences sont intentionnelles, coïncidences ou bugs.
la source
Près d'une décennie de retard pour cette fête, mais le nom de cet anti-modèle est Divergent Change , où plusieurs classes incluent des copies du même comportement, mais à mesure que le temps et la maintenance progressent et que certaines classes sont oubliées, ces comportements divergent.
Selon le comportement partagé et la façon dont il est partagé, il pourrait plutôt être appelé Shotgun Surgery , la différence étant qu'ici, une seule caractéristique logique est fournie par de nombreuses classes plutôt qu'une seule.
la source