Дублирование кода

Дублирование кода

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

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

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

Содержание

Откуда берутся дубликаты кода

Вот ряд причин по которым дубликаты кода могут быть созданы:

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

Проблемы к которым приводят дубликаты кода

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

  • Большое количество кода затрудняет его понимание: Дублирование кода часто приводит к созданию длинных, повторяющихся последовательностей кода которые отличаются лишь несколькими строками или символами.
  • Скрытое значение: Трудно уловить разницу в повторяющихся участках кода, и поэтому, становится тяжелее понимать для чего именно предназначен тот или иной кусочек кода. Зачастую, единственная разница заключается в параметрах. Лучший выход из данной ситуации лежит в использовании процедур и функций.
  • Аномалии обновления: Дублирование кода противоречит основному принципу теории баз данных, а именно: Избегайте избыточности. Невыполнение этого принципа приводит к аномалиям обновления, которые сильно увеличивают затраты на обслуживание кода. В этом случае одно и то же изменение нужно ввести во все дубликаты. И в лучшем случае, время потраченное на внесение изменений, и тестирование кода увеличивается пропорционально количеству дубликатов. А в худшем — некоторые места в коде могут быть пропущены, и исправление всех ошибок может затянутся на месяцы или даже года. Старайтесь использовать библиотеки кода в такой ситуации.
  • Размер файла: Без применения какого-либо сжатия, файл исходника будет занимать больше места на диске.

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

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

  • Алгоритм булочника (Baker’s algorithm).[2]
  • Визуальное определение дубликатов.[4]

Примеры дубликатов кода

Приведем следующий кусочек кода который вычисляет среднее массива целых чисел

extern int array1[];
extern int array2[];
 
int sum1 = 0;
int sum2 = 0;
int average1 = 0;
int average2 = 0;
 
for (int i = 0; i < 4; i++)
{
    sum1 += array1[i];
}
 
average1 = sum1/4;
 
for (int 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);

Инструменты для поиска дубликатов кода

Code duplication analysis tools include:

  • Atomiq — коммерческий продукт
  • Black Duck Software — коммерческий продукт (среда анализа кода)
  • CCFinder (C/C++, Java, COBOL, Fortran, и т. д. / некомфортный для компиляции в не-windows операционных системах)
  • CloneAnalyzer (C/C++ and Java / только как плагин для Eclipse)
  • CloneDR — коммерческий продукт (Ada, C, C++, C#, Java, COBOL, Fortran, Python, VB.net, VB6, PHP4/5, PLSQL, SQL2011, XML, и много других языков)
  • ConQAT[5][6] (Open Source, поддерживает: ABAP, ADA, Cobol, C/C++, C#, Java, PL/I, PL/SQL, Python, Text, Transact SQL, Visual Basic, XML)
  • JCCD — Гибкое API для обнаружения дубликатов кода для Java (Open Source: поддерживает Java, но может быть адаптирован для дургих языков с помощью ANTLR)
  • JPlag (Java, C#, C, C++, структурный и обычный текст)

См. также

Примечания

  1. Spinellis, Diomidis The Bad Code Spotter's Guide. InformIT.com. Архивировано из первоисточника 10 сентября 2012. Проверено 6 июня 2008.
  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
  4. Visual Detection of Duplicated Code by Matthias Rieger, Stephane Ducasse.
  5. A Workbench for Clone Detection Research by E. Juergens, F. Deissenboeck, B. Hummel
  6. Do Code Clones Matter? by E. Juergens, F. Deissenboeck, B. Hummel, S. Wagner
  7. CP-Miner: A Tool for Finding Copy-paste and Related Bugs in Operating System Code. by Zhenmin Li, Shan Lu, Suvda Myagmar and Yuanyuan Zhou.

Ссылки


Wikimedia Foundation. 2010.

Игры ⚽ Нужно решить контрольную?

Полезное


Смотреть что такое "Дублирование кода" в других словарях:

  • Разработка через тестирование — Разработка программного обеспечения Процесс разработки ПО Шаги процесса Анализ • Проектирование • Программирование • Докумен …   Википедия

  • Рефакторинг — (англ. refactoring) или реорганизация кода   процесс изменения внутренней структуры программы, не затрагивающий её внешнего поведения и имеющий целью облегчить понимание её работы[1][2]. В основе рефакторинга лежит последовательность… …   Википедия

  • C++ — У этого термина существуют и другие значения, см. C. См. также: Си (язык программирования) C++ Семантика: мультипарадигмальный: объектно ориентированное, обобщённое, процедурное, метапрограммирование Тип исполнения: компилируемый Появился в …   Википедия

  • C++11 — C++11[1][2] или ISO/IEC 14882:2011[3] (в процессе работы над стандартом носил условное наименование C++0x[4][5])  новая версия стандарта языка C++, вместо ранее действовавшего ISO/IEC 14882:2003. Новый стандарт включает дополнения в ядре… …   Википедия

  • C++0x — C++0x  будущая версия стандарта языка C++, вместо ныне существующего ISO/IEC 14882:2003. Новый стандарт будет включать дополнения в ядре языка и расширение STL, включая большую часть TR1  кроме, вероятно, библиотеки специальных… …   Википедия

  • Ruby on Rails — Ruby on Rails …   Википедия

  • Java — Иное название этого понятия  «Ява»; см. также другие значения. Не следует путать с JavaScript. Java Класс языка …   Википедия

  • Язык программирования Java — Java Класс языка: объектно ориентированный, структурный, императивный Появился в: 1995 г. Автор(ы): Sun Microsystems Последняя версия: Java Standard Edition 6 (1.6.14) Т …   Википедия

  • Джигарханян, Армен Борисович — Армен Джигарханян Արմեն Ջիգարխանյան Имя при рождении …   Википедия

  • избыточность — 03.01.05 избыточность (информация) [redundancy]: Характеристика информации, обеспечивающая повышение вероятности безошибочного считывания или передачи данных за счет их повтора1). 1Избыточность может также обеспечиваться добавлением функционально …   Словарь-справочник терминов нормативно-технической документации


Поделиться ссылкой на выделенное

Прямая ссылка:
Нажмите правой клавишей мыши и выберите «Копировать ссылку»