Дублирование кода (:rQlnjkfguny tk;g)

Перейти к навигации Перейти к поиску
Пример трёхкратного дублирования кода и избавления от этого запашка с помощью выделения метода и последующих вызовов кода созданного метода

Дублирование кода — явление в программировании, при котором некоторые участки исходного кода могут встречаться более чем однажды, как внутри одной, так и в нескольких программных сущностях. Является симптомом так называемого «дурно пахнущего кода».[1] В первую очередь потому, что увеличивается его длина; именно из-за дублирования, а не из-за совпадений. Последовательность дубликатов иногда называют клонами.

Некоторые причины, по которым две части кода могут считаться дубликатами:

  • посимвольное совпадение,
  • посимвольное совпадение, с игнорированием пробельных символов и комментариев,
  • совпадение по токенам (лексемам),
  • частичное совпадение по лексемам,
  • функциональное совпадение.

Одна из основных причин проявления дублирования — программирование копированием-вставками, при котором участки кода копируются просто потому, что «это работает». В большинстве случаев такая операция требует небольших изменений переносимого кода, например, переименования переменных или добавление и удаление некоторых участков. В ряде случаев требуется функциональность, которая очень похожа на уже существующую в другой части программы, и программист пишет код, очень близкий к тому, который уже существует.

Дублирование кода является признаком «низкого» или «ленивого» стиля программирования. Хороший стиль программирования обычно основан на повторном использовании кода. Может казаться, что использование дубликатов позволит несколько ускорить процесс создания программы, так как программисту не нужно будет задумываться над тем, как код уже используется и как он может использоваться в дальнейшем. Однако, проблема заключается в том, что написание кода — это лишь скромная часть жизненного цикла продукта, и дальнейшее сопровождение кода с дубликатами будет слишком осложнено. Проблемы, к которым приводит дублирование кода:

  • большое количество кода: дублирование часто приводит к созданию длинных, повторяющихся последовательностей кода, которые отличаются лишь несколькими строками или символами, что в итоге затрудняет понимание программы;
  • скрытое значение: трудно уловить разницу в повторяющихся участках кода и поэтому становится тяжелее понимать, для чего именно предназначен тот или иной кусок кода, зачастую единственная разница заключается в параметрах;
  • аномалии обновления: при обновлении дублированного кода необходимо обновить несколько аналогичных участков, что сильно увеличивает затраты на обслуживание;
  • размер исходного текста: без применения какого-либо сжатия исходный текст занимает больше места.

Поиск дубликатов кода

[править | править код]

Существует определённое количество алгоритмов, позволяющих отыскать дубликаты кода, среди них:

В ряде случаев эффективно визуальное определение дубликатов[4].

Следующий фрагмент кода вычисляет среднее значение массива целых чисел.

extern int array1[];
extern int array2[];

int sum1 = 0;
int sum2 = 0;
int average1;
int average2;
int i;

for (i = 0; i < 4; ++i)
  sum1 += array1[i];
average1 = sum1 / 4;

for (i = 0; i < 4; ++i)
  sum2 += array2[i];
average2 = sum2 / 4;

В нём два цикла могут быть выделены в отдельную функцию:

int calcAverage (int* Array_of_4)
{
  int sum = 0;

  for (int i = 0; i < 4; ++i)
    sum += Array_of_4[i];

  return sum / 4;
}

Использование этой функции избавит код от дубликатов:

extern int array1[];
extern int array2[];

int average1 = calcAverage(array1);
int average2 = calcAverage(array2);

Примечания

[править | править код]
  1. Spinellis, Diomidis The Bad Code Spotter's Guide. InformIT.com. Дата обращения: 6 июня 2008. Архивировано 10 сентября 2012 года.
  2. Brenda S. Baker. A Program for Identifying Duplicated Code. Computing Science and Statistics, 24:49-57, 1992
  3. Ira D. Baxter, et al. Clone Detection Using Abstract Syntax Trees Архивная копия от 10 августа 2017 на Wayback Machine
  4. Visual Detection of Duplicated Code Архивная копия от 29 июня 2006 на Wayback Machine by Matthias Rieger, Stephane Ducasse.