Иногда дублирование кода является результатом «каламбура»: две вещи выглядят одинаково, но это не так.
Возможно, что чрезмерное абстрагирование может нарушить истинную модульность вашей системы. При режиме модульности вы должны решить, "что может измениться?" и "что стабильно?" Все, что стабильно, помещается в интерфейс, а все, что нестабильно, инкапсулируется в реализацию модуля. Затем, когда все меняется, изменения, которые вам нужно сделать, изолируются от этого модуля.
Рефакторинг необходим, когда нужно изменить то, что вы считали стабильным (например, этот вызов API всегда будет принимать два аргумента).
Итак, для этих двух дублированных фрагментов кода я хотел бы спросить: обязательно ли изменение одного означает, что другое тоже должно быть изменено?
То, как вы ответите на этот вопрос, может дать вам лучшее представление о том, какой может быть хорошая абстракция.
Шаблоны проектирования также являются полезными инструментами. Возможно, ваш дублированный код выполняет обход некоторой формы, и шаблон итератора должен быть применен.
Если ваш дублированный код имеет несколько возвращаемых значений (и поэтому вы не можете сделать простой метод извлечения), то, возможно, вам следует создать класс, содержащий возвращаемые значения. Класс может вызывать абстрактный метод для каждой точки, которая варьируется между двумя фрагментами кода. Затем вы сделаете две конкретные реализации класса: по одной для каждого фрагмента. [Это, по сути, шаблон проектирования «Шаблонный метод», который не следует путать с концепцией шаблонов в C ++. В качестве альтернативы, то, на что вы смотрите, может быть лучше решено с помощью шаблона «Стратегия».]
Другой естественный и полезный способ думать об этом - это функции высшего порядка. Например, создание лямбды или использование анонимных внутренних классов для кода, чтобы перейти к абстракции. Как правило, вы можете удалить дублирование, но если между ними действительно нет отношения [если одно изменится, то же самое должно произойти и с другим], то вы можете причинять вред модульности, а не помогать ей.