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