복사 및 붙여넣기 프로그래밍

Copy-and-paste programming

복사/붙여넣기 프로그래밍은 때로 그저 붙여넣기라고 일컬어지기도 하지만 복사/붙여넣기 작업에 의해 만들어지는 고도로 반복적인 컴퓨터 프로그래밍 코드의 생산이다.그것은 주로 경멸적인 용어다; 그 용어를 사용하는 사람들은 종종 프로그래밍 역량의 부족을 암시한다.서브루틴이나 라이브러리가 일반적으로 대신 사용되기 때문에 기술 한계(예: 불충분하게 표현되는 개발 환경)의 결과일 수도 있다.단, 보일러 플레이트, 루프 언롤링(컴파일러가 자동으로 지원하지 않는 경우) 또는 특정 프로그래밍 숙어와 같이 복사·붙여넣기 프로그래밍이 허용되거나 필요하다고 간주되는 경우가 있으며, 일부 소스 코드 편집자가 스니펫 형태로 지원한다.

오리진스

복사/붙여넣기 프로그래밍은 종종 경험이 없거나 학생 프로그래머들에 의해 이루어지는데, 그들은 처음부터 코드를 쓰는 행위를 어렵거나 짜증나게 하고 미리 작성된 해결책이나 부분적인 해결책의 검색을 선호한다.[1](화물 컬트 프로그래밍 참조)

코드를 복사하는 경험이 없는 프로그래머들은 종종 그들이 취하고 있는 미리 쓰여진 코드를 완전히 이해하지 못한다.이처럼 문제는 복사나 붙여넣기 행위보다 프로그래밍에 대한 경험이 부족하고 용기가 부족해서 더 많이 발생한다.이 코드는 종종 친구나 동료의 코드, 인터넷 포럼, 학생의 교수/TA가 제공하는 코드 또는 컴퓨터 과학 교과서와 같은 서로 다른 소스로부터 온다.그 결과는 스타일들의 불균형한 충돌이 될 위험이 있으며, 새로운 솔루션이 더 이상 필요하지 않은 문제를 해결하는 불필요한 코드를 가질 수 있다.

또 다른 문제는 버그가 새로운 환경에 놓였을 때 더 이상 적용되지 않는 별도의 소스에서 이루어진 가정과 설계 선택에 의해 쉽게 도입될 수 있다는 것이다.

또한 변수, 클래스, 함수 등의 명칭은 새로운 맥락에서 목적이 완전히 다를 수 있지만 일반적으로 변경되지 않고 그대로 남아 있기 때문에 이러한 코드는 사실상 의도하지 않게 난독화될 수도 있다.[1]

복사/붙여넣기 프로그래밍은 또한 루프 구조, 기능 및 서브루틴과 같은 컴퓨터 언어에서 공통되는 특징을 잘 이해하지 못한 결과일 수 있다.

중복

기능과 같은 추상화 메커니즘을 사용하여 리팩터링되는 반복 코드.

라이브러리 코드 적용

복사 및 붙여넣기 역시 숙련된 프로그래머에 의해 행해지는데, 이들은 종종 특정 작업에 쉽게 적응할 수 있는 잘 테스트되고 바로 사용할 수 있는 코드 스니펫과 일반 알고리즘의 라이브러리를 가지고 있다.[2]

코드 복제의 한 형태인 복사/붙여넣기 프로그래밍은 몇 가지 본질적인 문제를 가지고 있다; 그러한 문제는 코드가 원본 텍스트와 사본 사이의 어떤 의미론적 연결도 보존하지 않으면 악화된다.이 경우 변경이 필요할 경우 중복된 모든 위치를 사냥하는 데 시간이 낭비된다.(원래 코드 및/또는 사본의 주석을 적절하게 달면 이 문제를 부분적으로 완화할 수 있지만, 그 경우에도 동일한 편집을 여러 번 하는 문제가 남아 있다.또한 코드 유지관리는 코멘트를 업데이트하는 것을 생략하는 경우가 많기 때문에 코드의 원격 부분을 찾는 곳을 설명하는 코멘트는 구식으로 악명 높다.)[3]

객체 지향 방법론의 추종자들은 복사 및 붙여넣기의 "코드 라이브러리" 사용에 더욱 반대한다.일반 알고리즘의 여러 개의 변형된 복사본을 만드는 대신에, 객체 지향 접근법은 알고리즘을 재사용 가능한 캡슐화클래스추상화할 것이다.클래스는 상속과부하를 전폭적으로 지원하여, 모든 통화 코드가 원문을 변형하지 않고 직접 이 일반 코드를 사용하도록 접속할 수 있도록 유연하게 작성된다.[4]추가 기능이 필요하므로 라이브러리를 확장(역호환성을 유지하면서)한다.이렇게 해서, 원래의 알고리즘에 고칠 버그가 있거나 개선할 수 있다면, 그것을 사용하는 모든 소프트웨어는 이익을 얻을 수 있다.

분기코드

분기 코드는 대규모 소프트웨어 개발의 일반적인 부분으로, 양 지점에서 병렬 개발이 가능하여 개발 주기가 단축된다.고전 분업에는 다음과 같은 특성이 있다.

  • 분기를 지원하는 버전 제어 시스템에 의해 관리됨
  • 지점은 병렬 개발이 완료되면 다시 합쳐진다.

복사 붙여넣기는 고전적인 가지에 대한 덜 공식적인 대안으로, 새로운 제품이 기존 제품에서 분리될 때와 같이 시간이 지남에 따라 가지가 점점 더 갈릴 것으로 예측될 때 종종 사용된다.

새로운 제품을 회전시키는 방법으로, 복사/붙여넣기 프로그래밍은 몇 가지 장점이 있다.새로운 개발 이니셔티브는 기존 제품의 코드를 건드리지 않기 때문에:

  • 기존 제품 테스트를 회귀할 필요가 없어 신제품 출시와 관련된 QA 시간을 절약하고 출시 시간을 단축할 수 있다.
  • 기존 제품에 버그가 도입될 위험이 없어 설치된 사용자 기반을 뒤엎을 수 있다.

단점은 다음과 같다.

  • 신제품이 기존 제품에서 예상한 것만큼 차이가 나지 않는다면 두 가지 코드 베이스가 지원될 필요가 있을 수 있다(비용의 두 배).이것은 값비싼 리팩토링과 수동합병으로 이어질 수 있다.
  • 중복된 코드 기반은 두 제품에 걸쳐 필요할 수 있는 변경을 구현하는 데 필요한 시간을 두 배로 늘린다. 이는 그러한 변경에 대한 시장 출시 시간을 증가시키며, 사실상 코드를 먼저 분기함으로써 달성한 모든 시간 이득을 없앨 수 있다.

위와 마찬가지로 복사 및 붙여넣기 접근방식의 대안은 모듈화된 접근방식이 될 것이다.

  • 먼저 두 제품에서 공유할 코드를 라이브러리에 포함하십시오.
  • 코드 베이스의 두 번째 복사본이 아닌 이러한 라이브러리를 신제품 개발의 기반으로 사용하십시오.
  • 제품의 추가 버전인 3번째, 4번째 또는 5번째 버전을 계획하는 경우, 이 접근방식은 기성 코드 라이브러리가 두 번째 이후 추가 제품의 개발 주기를 극적으로 단축하기 때문에 훨씬 더 강력하다.[5]

반복 작업 또는 태스크의 변형

복사 붙여넣기 프로그래밍에 의해 작성된 코드를 유지관리하는 어려움 및 위험

복사/붙여넣기 프로그래밍의 가장 해로운 형태 중 하나는 반복 작업을 수행하는 코드에서 발생하거나, 일부 변수에 따라 동일한 기본 작업을 변형하는 것이다.각 인스턴스는 위에서 복사한 후 다시 붙여넣고, 약간의 수정만 있으면 된다.유해한 영향은 다음과 같다.

  • 복사해서 붙여넣는 방식은 종종 큰 방법(악질 코드 냄새)으로 이어진다.
  • 각 인스턴스는 이전 섹션에서 논의된 모든 문제를 포함하여 코드 복제본을 생성하지만 훨씬 더 큰 범위를 가진다.수 많은 중복이 일반적이다; 수백 개의 중복이 가능하다.특히 버그 수정은 그러한 코드에서 매우 어렵고 비용이 많이 든다.[6]
  • 또한 그러한 코드는 각 반복마다 무엇이 다른지 정확히 파악하기가 어렵기 때문에 상당한 가독성 문제를 겪는다.이것은 코드 개정의 위험과 비용에 직접적인 영향을 미친다.
  • 절차적 프로그래밍 모델은 반복 작업에 대한 복사/붙여넣기 접근방식을 강하게 단념시킨다.절차 모델에서, 반복 작업에 대한 선호 접근방식은 작업을 통과하는 단일 패스를 수행하는 기능이나 서브루틴을 만드는 것이다. 이 서브루틴은 반복적으로 또는 더 잘, 어떤 형태의 루프 구조를 가지고 부모 루틴에 의해 호출된다.이러한 코드는 "잘 분해된"이라고 불리며, 읽기 쉽고 쉽게 확장 가능한 코드로 권장된다.[7]
  • 이 경우에 적용되는 일반적인 경험 법칙은 "자신을 반복하지 말라"이다.

신중한 설계 선택

복사/붙여넣기 프로그래밍은 때때로 유효한 프로그래밍 기법으로 받아들여진다.이것은 클래스 선언이나 표준 라이브러리 수입과 같은 보일러 플레이트에서 가장 흔히 볼 수 있으며, 기존 코드 템플릿(빈 내용 또는 스텁 기능이 있는)을 채울 프레임워크로 사용하는 경우에서 볼 수 있다.

프로그래밍 숙어와 설계 패턴의 사용은 공식 코드를 사용하므로 복사/붙여넣기 프로그래밍과 유사하다.경우에 따라 이것은 코드 조각으로 표현될 수 있는데, 프로그래머의 마음에서 단순히 상기되는 경우가 많지만, 그런 코드가 필요할 때 붙여넣을 수 있다.다른 경우에는 숙어를 코드 템플릿으로 줄일 수 없다.그러나 대부분의 경우 숙어를 코드로 줄일 수 있다 하더라도 함수로 추상화될 정도로 길거나 직접 키를 넣을 수 있을 정도로 짧을 것이다.

서브텍스트 프로그래밍 언어는 컷 앤 페이스트(cut and paste)를 '결정화'하기 위한 연구 프로젝트다.이 언어를 사용하면 절단 및 붙여넣기가 주된 상호작용 모델이며, 따라서 안티패턴으로 간주되지 않는다.

간단한 예는 다음과 같이 표현될 수 있는 루프에 대한 것이다.for (int i=0; i!=n; ++i) {}.

이러한 루프를 사용하는 샘플 코드는 다음과 같을 수 있다.

공허하게 하다 foo(인트로 n) {     을 위해 (인트로 i=0; i!=n; ++i) {        /* body */     } } 

다음 코드 조각(유형 및 변수 이름 지정)에 의해 루프 코드가 생성될 수 있었다.

    을 위해 ($type $val_var = 0; $val_var != 달러스톱; ++$val_var) {         /* body */     } 

참고 항목

참조

  1. ^ a b Yarmish, Gavriel; Kopec, Danny (2007). "Revisiting Novice Programmers Errors". ACM Sigcse Bulletin. acm.org. 39 (2): 131–137. doi:10.1145/1272848.1272896. S2CID 8854303. Retrieved 2008-06-04.
  2. ^ "Building ASP.NET Web Pages Dynamically in the Code-Behind". codeproject.com. 25 April 2008. Retrieved 2008-06-04.
  3. ^ Spinellis, Diomidis. "The Bad Code Spotter's Guide". InformIT.com. Retrieved 2008-06-06.
  4. ^ Lewallen, Raymond. "4 major principles of Object-Oriented Programming". codebetter.com. Archived from the original on 2010-11-25. Retrieved 2008-06-04.
  5. ^ Eriksen, Lisa. "Code Reuse In Object-Oriented Software Development" (PDF). Norwegian University of Science and Technology, Department of Computer and Information Science. Retrieved 2008-05-29.
  6. ^ Ashley Marsh. "Coding Standards – The Way to Maintainable Code". MAAN Softwares INC. Retrieved 2018-04-10.
  7. ^ "Stanford University, CS 106X ("Programming Abstractions") Course Handout: "Decomposition"" (PDF). Stanford University. Archived from the original (PDF) on May 16, 2008. Retrieved 2008-06-04.

외부 링크