A volte la duplicazione del codice è il risultato di un "gioco di parole": due cose sembrano uguali, ma non lo sono.
È possibile che l'eccessiva astrazione possa interrompere la vera modularità del sistema. Sotto il regime della modularità, devi decidere "che cosa potrebbe cambiare?" e "cos'è stabile?". Tutto ciò che è stabile viene inserito nell'interfaccia, mentre ciò che è instabile viene incapsulato nell'implementazione del modulo. Quindi, quando le cose cambiano, la modifica che devi apportare è isolata a quel modulo.
Il refactoring è necessario quando ciò che pensavi fosse stabile (ad es. Questa chiamata API prenderà sempre due argomenti) deve cambiare.
Quindi, per questi due frammenti di codice duplicati, vorrei chiedere: una modifica richiesta a uno significa necessariamente che anche l'altro deve essere cambiato?
Il modo in cui rispondi a questa domanda potrebbe darti una visione migliore di ciò che potrebbe essere una buona astrazione.
I modelli di progettazione sono anche strumenti utili. Forse il tuo codice duplicato sta attraversando una qualche forma e dovrebbe essere applicato il modello iteratore.
Se il tuo codice duplicato ha più valori di ritorno (ed è per questo che non puoi fare un semplice metodo di estrazione), allora forse dovresti creare una classe che contiene i valori restituiti. La classe potrebbe chiamare un metodo astratto per ogni punto che varia tra i due frammenti di codice. Dovresti quindi realizzare due implementazioni concrete della classe: una per ogni frammento. [Questo è effettivamente il modello di progettazione del metodo modello, da non confondere con il concetto di modelli in C ++. In alternativa, ciò che stai guardando potrebbe essere meglio risolto con il modello di strategia.]
Un altro modo naturale e utile per pensarci è con funzioni di ordine superiore. Ad esempio, creare lambda o utilizzare classi interne anonime affinché il codice passi all'astrazione. Generalmente, puoi rimuovere la duplicazione, ma a meno che non ci sia davvero una relazione tra loro [se uno cambia, così deve fare l'altro] allora potresti danneggiare la modularità, non aiutarla.