Ich bin sicher, dass es irgendwo einen Namen für dieses Anti-Muster gibt; Ich bin jedoch nicht genug mit der Anti-Muster-Literatur vertraut, um sie zu kennen.
Stellen Sie sich das folgende Szenario vor:
or0
ist eine Mitgliedsfunktion in einer Klasse. Ob gut oder schlecht, es hängt stark von Variablen der Klassenmitglieder ab. Programmierer A kommt und benötigt Funktionen wie, or0
aber anstatt aufzurufen or0
, kopiert Programmierer A die gesamte Klasse und benennt sie um. Ich vermute, dass sie nicht anruft, or0
weil es, wie gesagt, für seine Funktionalität stark von Mitgliedsvariablen abhängt. Oder vielleicht ist sie eine Junior-Programmiererin und weiß nicht, wie sie es von einem anderen Code aus aufrufen soll. Also jetzt haben wir or0
und c0
(c für Kopie). Ich kann Programmierer A für diesen Ansatz nicht vollständig bemängeln - wir alle haben enge Fristen und hacken Code, um die Arbeit zu erledigen.
Mehrere Programmierer warten, or0
so dass es jetzt Version ist orN
. c0
ist jetzt Version cN
. Leider or0
schienen sich die meisten Programmierer, die die Klasse enthielten , überhaupt nicht bewusst zu c0
sein - was eines der stärksten Argumente ist, die ich mir für die Weisheit des DRY-Prinzips vorstellen kann. Möglicherweise wurde der Code auch unabhängig gepflegt c
. So oder so scheint es, dass or0
und c0
unabhängig voneinander gehalten wurden. Und, Freude und Glück, es tritt ein Fehler auf cN
, der nicht auftritt orN
.
Ich habe also ein paar Fragen:
1.) Gibt es einen Namen für dieses Anti-Muster? Ich habe das so oft gesehen, dass es mir schwer fällt zu glauben, dass dies kein benanntes Anti-Muster ist.
2.) Ich sehe einige Alternativen:
a.) Fix orN
, um einen Parameter zu übernehmen, der die Werte aller benötigten Mitgliedsvariablen angibt. Ändern Sie dann cN
, um orN
alle erforderlichen Parameter aufzurufen, die übergeben wurden.
b.) Versuchen Sie, Fixes manuell von orN
bis zu portieren cN
. (Wohlgemerkt, ich möchte das nicht tun, aber es ist eine realistische Möglichkeit.)
c.) Wiederholen, orN
um noch cN
einmal, yuck, aber ich liste es der Vollständigkeit halber auf.
d.) Versuchen Sie herauszufinden, wo ein cN
Defekt vorliegt, und reparieren Sie ihn dann unabhängig davon orN
.
Alternative a scheint auf lange Sicht die beste Lösung zu sein, aber ich bezweifle, dass der Kunde mich diese implementieren lässt. Niemals Zeit oder Geld, um die Dinge richtig zu reparieren, sondern immer Zeit und Geld, um das gleiche Problem 40 oder 50 Mal zu beheben, oder?
Kann jemand andere Ansätze vorschlagen, die ich möglicherweise nicht in Betracht gezogen habe?
quelle
Antworten:
es heißt nur doppelter Code - ich kenne keine ausgefallenen Namen mehr dafür. Die langfristigen Folgen sind wie von Ihnen beschrieben und schlimmer.
Natürlich ist die Beseitigung der Duplizierung die ideale Option, wenn dies nur möglich ist. Es kann viel Zeit in Anspruch nehmen (in einem kürzlich in unserem Legacy-Projekt durchgeführten Fall wurden mehrere Methoden in mehr als 20 Unterklassen in einer Klassenhierarchie dupliziert, von denen viele im Laufe der Jahre ihre eigenen geringfügigen Unterschiede / Erweiterungen evolutionär vergrößert hatten Ich etwa 1,5 Jahre durch sukzessives Schreiben und Umgestalten von Unit-Tests, um alle Überschneidungen zu beseitigen. Ausdauer hat sich jedoch gelohnt.
In einem solchen Fall benötigen Sie möglicherweise noch eine oder mehrere der anderen Optionen als vorübergehende Korrekturen, selbst wenn Sie sich dazu entschließen, die Duplizierung zu beseitigen. Welche davon besser ist, hängt jedoch von vielen Faktoren ab, und ohne mehr Kontext raten wir nur.
Viele kleine Verbesserungen können auf lange Sicht einen großen Unterschied machen. Sie benötigen auch nicht unbedingt die ausdrückliche Genehmigung des Kunden für diese - ein kleines Refactoring jedes Mal, wenn Sie diese Klasse berühren, um einen Fehler zu beheben oder eine Funktion zu implementieren, kann im Laufe der Zeit viel bewirken. Nehmen Sie einfach etwas mehr Zeit für das Refactoring in Ihre Aufgabenschätzungen auf. Es ist genau wie bei der Standardwartung, die Software langfristig funktionsfähig zu halten.
quelle
Es gibt einen Verweis auf das WET- Muster (We Enjoy Typing), aber ich weiß nicht, ob es sich um einen Standardnamen handelt.
quelle
Wenn ich dich richtig verstehe, ist in der Klasse zu viel los. Dadurch entstehen Methoden, die nicht dem Prinzip der Einzelverantwortung folgen . Dies führt zu Code, der verschoben werden muss, wobei Teile genommen werden, während andere weggelassen werden. Dies könnte auch viele Mitglieder schaffen.
Sie sollten auch die Eingabehilfen-Modifikatoren überprüfen. Stellen Sie sicher, dass die Dinge, die öffentlich sind, tatsächlich öffentlich sein sollten. Der Verbraucher muss nicht über jedes kleine Mitglied Bescheid wissen ... verwenden Sie die Kapselung.
Dies erfordert einen Refactor. Es scheint auch, dass Code ohne Vorabentwurf geschrieben wird. Schauen Sie sich die testgetriebene Entwicklung an. Schreiben Sie den Code so, wie er aufgerufen werden soll, anstatt den Code aufzurufen, wie auch immer er implementiert ist. In TDD finden Sie einige Hinweise zur Ausführung der Aufgabe.
quelle
Wenn Sie Code kopieren, führen Sie eine technische Schuld der doppelten Wartung ein, genauer gesagt: Codeduplizierung .
Normalerweise wird dies durch Refactoring behoben. Insbesondere leiten Sie alle Aufrufe an eine neue Funktion (oder eine neue Methode in einer neuen Klasse) um, die den gemeinsamen Code enthält. Der einfachste Weg, um zu beginnen, besteht darin, den gesamten kopierten Code zu entfernen und zu sehen, welche Unterbrechungen Sie beheben, indem Sie die Aufrufe an den allgemeinen Code umleiten.
Es kann schwierig sein, Ihren Kunden dazu zu bringen, dem Refactor-Code zuzustimmen, da es schwierig ist, eine nicht-technische Person davon zu überzeugen, eine technische Schuld zu beheben. Wenn Sie das nächste Mal Zeitschätzungen vornehmen, geben Sie einfach die Zeit an, die erforderlich ist, um Ihre Schätzungen zu überarbeiten . In den meisten Fällen gehen Kunden davon aus, dass Sie den Code während der Korrektur bereinigen.
quelle
Klingt für mich nach Spaghetti-Code . Die beste Lösung ist ein Refactor / Rewrite.
quelle
Sie sagen, Sie können A nicht vollständig beschuldigen - aber das Kopieren einer Klasse auf diese Weise ist eigentlich unverzeihlich. Es ist ein massiver Fehler in Ihrem Codeüberprüfungsprozess. Es ist möglicherweise der massivste Fehler, da überhaupt keine Codeüberprüfung durchgeführt wurde.
WENN Sie jemals denken, dass Sie schrecklichen Code produzieren müssen, um eine Frist einzuhalten, sollte die absolut höchste Prioritätsanforderung für die Veröffentlichung danach darin bestehen, den schrecklichen Code JETZT zu reparieren. Ihr Problem ist also weg.
Das DRY-Prinzip gilt für Situationen, die nicht ganz perfekt sind und verbessert werden können. Das Duplizieren einer Klasse ist ein völlig neues Kaliber. Ich würde es zuerst "duplizierter Code" nennen, und im Laufe der Zeit wird es sich in den schlimmsten aller Zeitverschwender verwandeln, "divergierenden duplizierten Code": mehrere Kopien desselben Codes, die fast, aber nicht ganz identisch sind, und niemand weiß, ob Die Unterschiede sind beabsichtigt, Zufall oder Fehler.
quelle
Fast ein Jahrzehnt zu spät zu dieser Party, aber der Name dieses Anti-Musters ist Divergent Change , wo mehrere Klassen Kopien desselben Verhaltens enthalten, aber wenn Zeit und Wartung fortschreiten und einige Klassen vergessen werden, weichen diese Verhaltensweisen voneinander ab.
Abhängig davon, was das gemeinsame Verhalten ist und wie es geteilt wird, könnte es stattdessen als Shotgun Surgery bezeichnet werden. Der Unterschied besteht darin, dass hier ein einzelnes logisches Merkmal von vielen Klassen bereitgestellt wird und nicht von einem einzelnen.
quelle