{{위키데이터 속성 추적}}
[[파일:Duplicate code.gif|thumbnail|코드를 메소드로 대체하여 수행한 중복 코드 해결의 예.]]

'''중복 코드'''는 동일한 실체가 소유하거나 유지 보수하고 있는 하나의 프로그램 내에서 또는 각기 다른 프로그램 내에서 한 번 이상 발생하는 일련의 [[소스 코드]]를 가리키는 [[컴퓨터 프로그래밍]] 용어이다. 중복 코드는 보통 [[코드 스멜|바람직하지 않는데]] 여기에는 수많은 이유가 있다.<ref>{{웹 인용|url=http://www.informit.com/articles/article.aspx?p=457502&seqNum=5|title=The Bad Code Spotter's Guide|publisher=InformIT.com|accessdate=2008-06-06|first=Diomidis|last=Spinellis|보존url=https://web.archive.org/web/20121018012312/http://www.informit.com/articles/article.aspx?p=457502&seqNum=5|보존날짜=2012-10-18|url-status=dead}}</ref> 중복 코드의 최소한의 요건은 동시다발적 유사성 보다는 연속적으로 중복되는 것으로 보이는 코드의 양에 적용된다. 중복 코드의 연속은 코드 클론(code clone), 간단히 클론(clone)이라고도 하며 소스 코드 내에서 중복을 찾는 자동화된 과정은 클론 감지(clone detection)라고 한다.

== 중복을 일으키는 원리 ==
중복 코드가 발생하는 이유들 중에는 [[복사해서 붙여넣기 프로그래밍]]을 포함하는데, 여기에서 학문적인 문맥에서 [[표절]], 징발의 일부로 간주될 수도 있으며 그저 동작하기 때문에 코드의 부분이 복사되는 것이다. 대부분의 경우 이러한 작업에는 변수 이름 변경이나 코드 추가/삭제와 같은 복제된 코드 내의 사소한 수정이 수반된다. 언어적인 측면에서는 코드의 한 복사본을 여러 목적으로 다룰 수 있게 하는 기능을 거의 늘 제공하지만 프로그래머가 적절하게 이를 처리할 시간이 부족해서가 아니라, 또 [[소프트웨어 부후증]]의 증가를 고려해서가 아닌, 해당 언어를 잘 알지 못해서 복사본이 만들어진다.

프로그램의 다른 일부분과 매우 비슷한 기능을 포함하는 경우도 있으며 개발자가 독립적으로 다른 곳에 존재하는 것과 매우 비슷한 코드를 작성할 수 있다. 여러 연구에 따르면 이렇게 독립적으로 작성된 코드는 일반적으로 문법적으로 유사하지 않다.<ref>[https://www.cqse.eu/publications/2010-code-similarities-beyond-copy-paste.pdf Code similarities beyond copy & paste] by Elmar Juergens, Florian Deissenboeck, Benjamin Hummel.</ref><ref>Stefan Wagner, Asim Abdulkhaleq, Ivan Bogicevic, Jan-Peter Ostberg, Jasmin Ramadani. [https://peerj.com/articles/cs-49/?td=wk How are functionally similar code clones syntactically different? An empirical study and a benchmark] ''PeerJ Computer Science'' 2:e49. [[doi:10.7717/peerj-cs.49]]</ref>

개발 속도나 용이성을 증가하기 위해 복제 코드의 생성을 필요로 하는 자동으로 생성되는 코드는 중복의 또다른 이유이기도 하다. 실제 생성기에는 소스 코드에 중복을 포함하지 않고 만들어내는 출력에만 영향을 미친다.

== 비용과 이점 ==
[[보안 취약점|소프트웨어 취약점]]이 있는 코드가 복사될 때 개발자가 이러한 사본을 알지 못하는 경우 취약점은 계속해서 복사된 코드에 남아있게 된다.<ref>{{저널 인용|last1=Li|first1=Hongzhe|last2=Kwon|first2=Hyuckmin|last3=Kwon|first3=Jonghoon|last4=Lee|first4=Heejo|title=CLORIFI: software vulnerability discovery using code clone verification|journal=Concurrency and Computation: Practice and Experience|date=25 April 2016|volume=28|issue=6|pages=1900–1917|doi=10.1002/cpe.3532|accessdate=5 April 2017}}</ref> 코드 중복을 사용하면 컴파일 시간의 단축, [[인지 부하]]의 감소, [[인적 오류]]의 감소, 코드를 잊거나 간과하는 일의 감소를 달성할 수 있다. 그러나 모든 코드 중복이 리팩터링이 될 수 있는 것은 아니다.<ref>{{저널 인용|last1=Arcelli Fontana|first1=Francesca|last2=Zanoni|first2=Marco|last3=Ranchetti|first3=Andrea|last4=Ranchetti|first4=Davide|title=Software Clone Detection and Refactoring|journal=ISRN Software Engineering|date=2013|volume=2013|pages=1–8|doi=10.1155/2013/129437|accessdate=5 April 2017}}</ref> 프로그래밍 언어가 특히 [[동시 편집]]과 같은 사용자 인터페이스 기법과 함께 지원되는 경우 부적절하거나 과도하게 복잡한 추상화를 제공한다면 복제 자체가 가장 효율적인 해결책이 될 수 있다. 게다가, 리팩토링을 할 때 코드를 분리하는 것이 어떠한 유지보수적 이익 보다 더 중요할 수 있다.<ref>Kapser, C.; Godfrey, M.W., [http://plg2.cs.uwaterloo.ca/~migod/papers/2006/wcre06-clonePatterns.pdf ""Cloning Considered Harmful" Considered Harmful]," 13th Working Conference on Reverse Engineering (WCRE), pp. 19-28, Oct. 2006</ref> 중복 코드는 중복되지 않은 코드 보다 상당히 더 오류가 있는 경향이 있는 것으로 보이지는 않는다.<ref>{{저널 인용|last=Wagner|first=Stefan|last2=Abdulkhaleq|first2=Asim|last3=Kaya|first3=Kamer|last4=Paar|first4=Alexander|date=2016|title=On the relationship of inconsistent software clones and faults: an empirical study|url=http://elib.uni-stuttgart.de/opus/volltexte/2016/10526/|journal=Proc. 23rd IEEE International Conference on Software Analysis, Evolution, and Reengineering (SANER 2016)|doi=|pmid=|access-date=}}</ref>

== 중복 코드의 감지 ==
중복 코드를 찾기 위해 수많은 여러 알고리즘들이 제안되었다. 이를테면 다음과 같다:
* [[브렌다 베이커|베이커]] 알고리즘.<ref>[[Brenda Baker|Brenda S. Baker]]. ''A Program for Identifying Duplicated Code.'' Computing Science and Statistics, 24:49-57, 1992.</ref>
* [[라빈-카프 문자열 검색 알고리즘]].
* [[추상 구문 트리]]를 사용.<ref>Ira D. Baxter, et al. [http://www.semanticdesigns.com/Company/Publications/ICSM98.pdf Clone Detection Using Abstract Syntax Trees]</ref>
* 시각적 클론 감지(Visual clone detection).<ref>[http://www.iam.unibe.ch/~scg/Archive/Papers/Rieg98aEcoopWorkshop.pdf Visual Detection of Duplicated Code] {{웨이백|url=http://www.iam.unibe.ch/~scg/Archive/Papers/Rieg98aEcoopWorkshop.pdf |date=20060629083352 }} by Matthias Rieger, Stephane Ducasse.</ref>
* 카운트 매트릭스 클론 감지(Count Matrix Clone Detection).<ref>Yuan, Y. and Guo, Y.  ''CMCD: Count Matrix Based Code
Clone Detection,'' in 2011 18th Asia-Pacific Software Engineering Conference. IEEE, Dec. 2011, pp. 250-257.</ref><ref>Chen, X., Wang, A. Y., & Tempero, E. D. (2014). [http://www.qualitascorpus.com/pubs/ChenWangTemperoClones.pdf A Replication and Reproduction of Code Clone Detection Studies]. In ACSC (pp. 105-114).</ref>
* [[:en:Locality-sensitive hashing|Locality-sensitive hashing]]

== 기능적 중복 코드의 예 ==
[[정수]]의 [[배열]]의 [[평균]]을 셈하는 다음의 [[스니펫|코드 스니펫]]이 있다고 하자.

<syntaxhighlight lang="c">
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;
</syntaxhighlight>

2개의 루프를 하나의 함수로 재작성할 수 있다:
<syntaxhighlight lang="c">
int calc_average_of_four(int* array) {
   int sum = 0;
   for (int i = 0; i < 4; i++)
       sum += array[i];

   return sum / 4;
}
</syntaxhighlight>

위의 함수를 사용하면 루프 중복이 없는 소스 코드를 제공한다:
<syntaxhighlight lang="c">
extern int array1[];
extern int array2[];

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

</syntaxhighlight>

이 사소한 경우에서 컴파일러는 해당 함수로 향하는 두 호출에 대한 [[인라인 확장|인라인]]을 선택할 수 있으며 위의 예처럼 기계 코드가 중복되거나 중복되지 않을 수 있다. 함수가 인라인 처리되지 않으면 추가적인 함수 호출의 부하가 발생하여 실행에 시간이 더 소요될 수 있다. 이론적으로 실행 시 추가 시간은 문제가 될 수 있다.

== 같이 보기 ==
* [[안티패턴]]
* [[중복배제]]

== 각주 ==
{{각주|30em}}

== 외부 링크 ==
* [https://archive.today/20121211121637/http://students.cis.uab.edu/tairasr/clones/literature/ The University of Alabama at Birmingham: Code Clones Literature]
* [http://alexdresko.com/2010/09/09/finding-duplicate-code-in-c-vb-net-aspx-ruby-python-java-c-c-actionscript-or-xaml Finding duplicate code in C#, VB.Net, ASPX, Ruby, Python, Java, C, C++, ActionScript, or XAML]

[[분류:안티패턴]]
[[분류:소스 코드]]
[[분류:소프트웨어 메트릭]]