Manchmal ist Code-Duplikation das Ergebnis eines "Wortspiels": Zwei Dinge sehen gleich aus, sind es aber nicht.
Möglicherweise kann eine Überabstraktion die wahre Modularität Ihres Systems sprengen. Im Rahmen der Modularität müssen Sie sich entscheiden, "was sich voraussichtlich ändern wird". und "was ist stabil?". Was stabil ist, wird in die Schnittstelle gestellt, während was instabil ist, in die Implementierung des Moduls eingeschlossen wird. Wenn sich die Dinge ändern, wird die Änderung, die Sie vornehmen müssen, auf dieses Modul beschränkt.
Refactoring ist erforderlich, wenn das, was Sie für stabil hielten (z. B. dieser API-Aufruf benötigt immer zwei Argumente), geändert werden muss.
Für diese beiden duplizierten Codefragmente würde ich also fragen: Bedeutet eine Änderung an dem einen unbedingt, dass auch der andere geändert werden muss?
Wie Sie diese Frage beantworten, gibt Ihnen möglicherweise einen besseren Einblick in das, was eine gute Abstraktion sein könnte.
Entwurfsmuster sind auch nützliche Werkzeuge. Möglicherweise durchläuft Ihr duplizierter Code eine bestimmte Form, und das Iterationsmuster sollte angewendet werden.
Wenn Ihr duplizierter Code mehrere Rückgabewerte enthält (und Sie deshalb keine einfache Extraktionsmethode ausführen können), sollten Sie möglicherweise eine Klasse erstellen, die die zurückgegebenen Werte enthält. Die Klasse kann für jeden Punkt eine abstrakte Methode aufrufen, die zwischen den beiden Codefragmenten variiert. Sie würden dann zwei konkrete Implementierungen der Klasse vornehmen: eine für jedes Fragment. [Dies ist effektiv das Entwurfsmuster der Vorlagenmethode, nicht zu verwechseln mit dem Konzept der Vorlagen in C ++. Alternativ könnte das, was Sie sich ansehen, mit dem Strategiemuster besser gelöst werden.]
Eine andere natürliche und nützliche Art, darüber nachzudenken, sind Funktionen höherer Ordnung. Zum Beispiel Lambdas erstellen oder anonyme innere Klassen verwenden, damit der Code an die Abstraktion übergeben wird. Im Allgemeinen können Sie Duplikate entfernen, aber wenn es nicht wirklich eine Beziehung zwischen ihnen gibt (wenn sich eines ändert, muss sich das andere ändern), kann dies die Modularität beeinträchtigen, ohne Abhilfe zu schaffen.