Parfois, la duplication de code est le résultat d'un "jeu de mots": deux choses se ressemblent, mais ne le sont pas.
Il est possible qu'une surabrégé excessif puisse briser la véritable modularité de votre système. Sous le régime de la modularité, vous devez décider "qu'est-ce qui est susceptible de changer?" et "qu'est-ce qui est stable?". Tout ce qui est stable est mis dans l'interface, tandis que tout ce qui est instable est encapsulé dans l'implémentation du module. Ensuite, lorsque les choses changent, la modification que vous devez effectuer est isolée de ce module.
Le refactoring est nécessaire lorsque ce que vous pensiez être stable (par exemple, cet appel API prendra toujours deux arguments) doit changer.
Donc, pour ces deux fragments de code dupliqués, je demanderais: un changement requis pour l'un signifie-t-il nécessairement que l'autre doit également être changé?
La façon dont vous répondez à cette question pourrait vous donner une meilleure idée de ce qu'est une bonne abstraction.
Les modèles de conception sont également des outils utiles. Peut-être que votre code dupliqué effectue une traversée d'une forme quelconque, et le modèle d'itérateur doit être appliqué.
Si votre code dupliqué a plusieurs valeurs de retour (et c'est pourquoi vous ne pouvez pas faire une méthode d'extraction simple), alors vous devriez peut-être créer une classe qui contient les valeurs renvoyées. La classe pourrait appeler une méthode abstraite pour chaque point qui varie entre les deux fragments de code. Vous feriez alors deux implémentations concrètes de la classe: une pour chaque fragment. [Il s'agit en fait du modèle de conception de la méthode de modèle, à ne pas confondre avec le concept de modèles en C ++. Alternativement, ce que vous regardez pourrait être mieux résolu avec le modèle de stratégie.]
Une autre façon naturelle et utile d'y penser est d'utiliser des fonctions d'ordre supérieur. Par exemple, créer des lambdas ou utiliser des classes internes anonymes pour que le code passe à l'abstraction. En général, vous pouvez supprimer la duplication, mais à moins qu'il n'y ait vraiment une relation entre eux [si l'un change, il en va de même pour l'autre], vous risquez de nuire à la modularité, de ne pas l'aider.