Повторяющийся код
В компьютерном программировании дублирующийся код — это последовательность исходного кода , которая встречается более одного раза либо внутри программы, либо в разных программах, принадлежащих или поддерживаемых одной и той же организацией. Дублирующийся код обычно считается нежелательным по ряду причин. [1] Минимальное требование обычно применяется к количеству кода, который должен появиться в последовательности, чтобы он считался дублирующим, а не случайно похожим. Последовательности дублированного кода иногда называют клонами кода или просто клонами. Автоматизированный процесс поиска дубликатов в исходном коде называется обнаружением клонов.
Две кодовые последовательности могут быть дубликатами друг друга, но при этом не быть идентичными посимвольно, например, будучи посимвольно идентичными только тогда, когда пробельные символы и комментарии игнорируются, или будучи идентичными посимвольно или токеном. -для токена идентично со случайными вариациями. Даже последовательности кода, идентичные только функционально, могут считаться дублирующим кодом.
Появление
[ редактировать ]Некоторые из способов создания дублированного кода:
- копирование и вставка программирования , что в академических условиях может считаться плагиатом.
- поиск, при котором фрагмент кода копируется «потому что он работает». В большинстве случаев эта операция включает в себя небольшие изменения в клонированном коде, например переименование переменных или вставку/удаление кода. Язык почти всегда позволяет вызывать одну копию кода из разных мест, чтобы она могла служить нескольким целям, но вместо этого программист создает другую копию, возможно, потому, что они
- не понимаю язык должным образом
- у вас нет времени, чтобы сделать это должным образом, или
- плевать на возросшую активную гниль ПО .
Также может случиться так, что требуется функциональность, очень похожая на ту, что есть в другой части программы, и разработчик самостоятельно пишет код, очень похожий на тот, что существует где-то еще. Исследования показывают, что такой независимо переписанный код обычно не является синтаксически схожим. [2]
Еще одной причиной дублирования является автоматически генерируемый код, где дублирование кода может быть желательно для увеличения скорости или простоты разработки. Обратите внимание, что фактический генератор не будет содержать дубликатов в своем исходном коде, а только выходные данные, которые он производит.
Исправление
[ редактировать ]Дублированный код чаще всего устраняется путем перемещения кода в отдельный модуль ( функцию или модуль) и вызова этого модуля из всех мест, где он изначально использовался. Использование более открытого стиля разработки, при котором компоненты находятся в централизованном расположении, также может помочь в дублировании.
Затраты и выгоды
[ редактировать ]Код, включающий дублирующиеся функции, труднее поддерживать, потому что:
- это просто длиннее, и
- если он нуждается в обновлении, существует опасность, что одна копия кода будет обновлена без дальнейшей проверки наличия других экземпляров того же кода.
С другой стороны, если одна копия кода используется для разных целей и она не документирована должным образом, существует опасность, что она будет обновляться для одной цели, но это обновление не будет обязательным или соответствующим другой. целей.
Эти соображения не актуальны для автоматически генерируемого кода, если в исходном коде имеется только одна копия функциональности.
Раньше, когда объем памяти был более ограничен, дублирующийся код имел дополнительный недостаток: он занимал больше места, но сегодня это вряд ли станет проблемой.
кода с уязвимостью программного обеспечения уязвимость может продолжать существовать в скопированном коде, если разработчик не знает о таких копиях. При копировании [3] Рефакторинг дублированного кода может улучшить многие показатели программного обеспечения, такие как количество строк кода , цикломатическая сложность и связанность . Это может привести к сокращению времени компиляции, снижению когнитивной нагрузки , уменьшению количества человеческих ошибок и меньшему количеству забытых или пропущенных фрагментов кода. Однако не все дублирования кода можно рефакторить. [4] Клоны могут быть наиболее эффективным решением, если язык программирования предоставляет неадекватные или слишком сложные абстракции, особенно если они поддерживаются такими методами пользовательского интерфейса, как одновременное редактирование . Более того, риски взлома кода при рефакторинге могут перевесить любые преимущества от обслуживания. [5] Исследование Вагнера, Абдулхалека и Кайи пришло к выводу, что, хотя для синхронизации дубликатов необходима дополнительная работа, если вовлеченные программисты знают о дублирующемся коде, то ошибок возникает не значительно больше, чем в недублированном коде. [6] [ оспаривается – обсуждаем ]
Обнаружение повторяющегося кода
[ редактировать ]Для обнаружения дублированного кода был предложен ряд различных алгоритмов. Например:
- . Алгоритм Бейкера [7]
- Алгоритм поиска строки Рабина-Карпа .
- Использование абстрактных синтаксических деревьев . [8]
- Визуальное обнаружение клонов. [9]
- Подсчет обнаружения клонов матрицы. [10] [11]
- Хэширование с учетом местоположения
- Антиобъединение [12]
Пример функционально дублирующегося кода
[ редактировать ]Рассмотрим следующий фрагмент кода для вычисления среднего значения массива . целых чисел
extern int array_a[];
extern int array_b[];
int sum_a = 0;
for (int i = 0; i < 4; i++)
sum_a += array_a[i];
int average_a = sum_a / 4;
int sum_b = 0;
for (int i = 0; i < 4; i++)
sum_b += array_b[i];
int average_b = sum_b / 4;
Два цикла можно переписать как одну функцию:
int calc_average_of_four(int* array) {
int sum = 0;
for (int i = 0; i < 4; i++)
sum += array[i];
return sum / 4;
}
или, что обычно предпочтительнее, путем параметризации количества элементов в массиве.
Использование вышеуказанной функции даст исходный код, в котором нет дублирования циклов:
extern int array1[];
extern int array2[];
int average1 = calc_average_of_four(array1);
int average2 = calc_average_of_four(array2);
Обратите внимание, что в этом тривиальном случае компилятор может выбрать встраивание обоих вызовов функции, так что результирующий машинный код будет идентичен как для дублированных, так и для недублированных примеров выше. Если функция не встроена, то дополнительные затраты на вызовы функций , вероятно, займут больше времени (порядка 10 инструкций процессора для большинства высокопроизводительных языков). Теоретически, это дополнительное время для бега может иметь значение.

См. также
[ редактировать ]- Принцип абстракции (программирование)
- Антипаттерн
- Дедупликация данных
- Не повторяйся (СУХОЙ)
- Список инструментов для статического анализа кода
- Дублирующий код
- Правило трех (компьютерное программирование)
Ссылки
[ редактировать ]- ^ Спинеллис, Диомидис. «Руководство по обнаружению плохого кода» . ИнформИТ.com . Проверено 6 июня 2008 г.
- ^ Сходства кода, выходящие за рамки копирования и вставки, авторы: Элмар Юргенс, Флориан Дейсенбёк, Бенджамин Хаммель.
- ^ Ли, Хунчжэ; Квон, Хёкмин; Квон, Чонхун; Ли, Хиджо (25 апреля 2016 г.). «CLORIFI: обнаружение уязвимостей программного обеспечения с использованием проверки клонирования кода». Параллелизм и вычисления: практика и опыт . 28 (6): 1900–1917. дои : 10.1002/cpe.3532 . S2CID 17363758 .
- ^ Арчелли Фонтана, Франческа; Занони, Марко; Ранчетти, Андреа; Ранчетти, Давиде (2013). «Обнаружение и рефакторинг клонов программного обеспечения» (PDF) . ISRN Разработка программного обеспечения . 2013 : 1–8. дои : 10.1155/2013/129437 .
- ^ Капсер, К.; Годфри, М.В., «Клонирование считается вредным» , 13-я рабочая конференция по обратному проектированию (WCRE), стр. 19–28, октябрь 2006 г.
- ^ Вагнер, Стефан; Абдулхалек, Асим; Кая, Камер; Паар, Александр (2016). «О взаимосвязи несовместимых клонов программного обеспечения и ошибок: эмпирическое исследование» . 2016 23-я Международная конференция IEEE по анализу, эволюции и реинжинирингу программного обеспечения (SANER) . стр. 79–89. arXiv : 1611.08005 . дои : 10.1109/SANER.2016.94 . ISBN 978-1-5090-1855-0 . S2CID 3154845 .
- ^ Бренда С. Бейкер . Программа для выявления дублированного кода. Информатика и статистика, 24:49–57, 1992.
- ^ Ира Д. Бакстер и др. Обнаружение клонов с использованием абстрактных синтаксических деревьев
- ^ Визуальное обнаружение дублированного кода. Архивировано 29 июня 2006 г. в Wayback Machine Матиасом Ригером и Стефаном Дюкассом.
- ^ Юань, Ю. и Го, Ю. CMCD: Обнаружение клонов кода на основе матрицы подсчета, 18-я Азиатско-Тихоокеанская конференция по разработке программного обеспечения, 2011 г. IEEE, декабрь 2011 г., стр. 250–257.
- ^ Чен, X., Ван, AY, и Темперо, ED (2014). Репликация и воспроизведение исследований по обнаружению клонов кода . В ACSC (стр. 105-114).
- ^ Bulychev, Peter, and Marius Minea. " Duplicate code detection using anti-unification ." Proceedings of the Spring/Summer Young Researchers’ Colloquium on Software Engineering. No. 2. Федеральное государственное бюджетное учреждение науки Институт системного программирования Российской академии наук, 2008.