프로그래머가 아닌 사람에게 복사-붙여 넣기 프로그래밍의 위험성을 설명하는 좋은 간결한 방법은 무엇입니까? [닫은]


27

프로그래머가 아닌 사람에게 복사-붙여 넣기 프로그래밍의 문제를 설명 할 수있는 좋은 비유 나 은유를 찾고 있습니다. 잠재적 인 고객을 위해 코드 / 시스템 검토를 수행하는 경우가 종종 있으며, 일반적인 문제 중 하나는 코드 기반 전체에 엄청난 양의 복사-붙여 넣기 코드입니다. 리뷰에서 일상적으로 부르는 것입니다. 왜 이것이 문제인지 설명해야 할 때마다 (재사용이 좋은지 이해하기에는 프로그래밍에 대해 충분히 알고 있지만 이유를 이해하기에는 충분하지 않은 클라이언트에게는 특히 어렵습니다. 복사-붙여 넣기는 재사용의 좋은 형태가 아닙니다). 분명히 코드 유지 관리 측면에서 문제를 설명 할 수는 있지만 프로그래머가 아닌 사람들과 함께 할 수있는이 문제에 대해 간결하고 간결한 유추를하는 것이 좋습니다. 유추를 통해 검색 및 교체가이 문제에 효과적인 솔루션이 아닌 이유를 설명하면 보너스입니다. 어떤 제안?

명확히하기 위해 (아래 Jaroslav의 답변을 기반으로 함)-여기서는 코드 스 니펫을 사용하는 것에 대해 이야기하지 않습니다. 내가 보는 (방해되는) 방대한 양의 코드 또는 10 줄의 코드를 복사하여 붙여 넣기하여 몇 가지 PHP 또는 ASP.NET 페이지에 일부 사용자 데이터 (인라인 SQL 쿼리로 완료)를 붙여 넣습니다. 따라서 동일한 프로젝트의 다른 곳에서 코드를 복제하십시오.

업데이트 : 여기에 정말 좋은 답변이 몇 가지 있습니다. 의견에서 Scott Whitlock의 답변을 선택한 이유를 설명했지만 제조에 익숙한 고객을 다루는 경우 whatsisname의 답변을 적극 권장합니다.


흠, 그것은 힘든 일입니다. 그것은 고전적인 자동차 / 건물 / 공장 비유로 잘 번역되지 않습니다 .....
whatsisname

3
미국 공법에서 공화당과 민주당을 언급 한 다음 세 번째를 추가하면서 당사자 중 하나의 이름을 바꾸는 것을 상상해보십시오. 많은 법을 다시 써야 할 것입니다.
Job

위키, 포럼 등에서 이해하지 못하는 복사 붙여 넣기 코드 (안전하지 않은, 잘못된 구조 등)는 전자 메일 첨부 파일 (바이러스, 스파이웨어, 스팸 등)을 여는 것과 비슷합니다. 타사?
sakisk

@faif : 복사하여 붙여 넣은 코드가 반드시 가비지 코드 인 것은 아닙니다. 사무실 옆 사람이 작성한 코드가 좋을 수도 있습니다. 복사하여 붙여 넣은 코드의 문제점은 관리가 불가능한 유지 관리 / 논쟁의 악몽이된다는 것입니다.
whatsisname

1
@faif : 그런 다음 괄호로 묶인 섹션
whatsisname

답변:


36

이건 ... 집에 시계가 하나 있습니다. 큰! 당신은 몇 시인 지 알지만 항상 그것을 보려면 한 방으로 가야합니다.

그러나 물론 당신은 항상 그 방에 가지 않고 시간을 알고 싶기 때문에 시계를 더 사서 집 주변에 배포합니다. 이러한 각 시계는 독립적입니다. 그들은 모두 자신의 시간을 유지합니다. 이것은 다음을 의미합니다.

  • 일광 절약 시간 제로 인해 시간이 변경되면 모든 시간을 변경해야합니다
  • 모두 설정 되었더라도 모두 조금 다르며 완벽하게 동의하지는 않습니다. 시간이 지남에 그들은 표류했다.

이제 수십 또는 수백 개의 시계가있는 대규모 시설에서 같은 문제를 상상해보십시오. 그렇기 때문에 중앙 시간 기반과 동기화되는 네트워크 시계 와 같은 것이 필요 합니다. 그렇게하면 시간이 한 번만 정의 됩니다 .

복사-붙여 넣기 프로그래밍은 더 독립적 인 시계를 구입하는 것과 같습니다. 확장되지 않습니다.


1
필자가보고있는 대부분의 소프트웨어는 서비스 분야의 사람들을위한 소프트웨어이고 제조 유추는 이해하기 어려운 경우가 많기 때문에이 답변을 선택했습니다. 그러나 거의 모든 사람들이 집에 여러 시계를 가지고 있습니다. 나는 또한 검색 및 교체가 왜 필요한지 설명하는 방법으로 집안의 각 시계마다 시간을 변경하는 다른 프로세스가 있고 다른 양으로 빠르거나 느리다는 사실을 사용할 수 있기 때문에 그것을 좋아합니다. 복사-붙여 넣기 코드를 유지하기위한 옵션이 아닙니다.
EZ Hart

38

항공기를 설계한다고 상상해보십시오. 단일 엔진 제트기가 있습니다. 잘 팔립니다. 이제 바다를 가로 질러 장거리 운송을위한 4 개의 엔진 항공기를 설계 할 것입니다.

이제 각 개별 엔진에 대한 전체 엔지니어링 사양 및 도면 세트를 작성하지 않습니까? 아니요, 네 곳 모두에서 같은 엔진을 사용합니다. 이제 4 세트의 도면이 있고 무언가를 변경해야한다고 상상해보십시오. 이제 네 개의 엔진 도면 모두에서 변경해야합니다. 간격을두고 4 번째 엔진에서 실수로 무언가를 변경하는 것을 잊어 버리면 어떻게됩니까?

따라서 나사 길이 또는 파이프 나사산을 변경한다고 가정하십시오. 이제 엔지니어링 도면 데이터베이스에서 "검색 및 교체"를 할 수 없으며 연료 펌프의 장착 나사가 같은 크기로 인해 실수로 변경 될 수 있습니다. 또는 테일 키에 동력을 공급하는 유압 라인은 동일한 나사산을 사용했지만 이제는 다르며 더 이상 테일에 동력을 공급할 수 없습니다.

이제 플로리다 남쪽으로 날아가는 동안 엔진이 터빈 블레이드를 무작위로 던지고 폭발하기 때문에 NTSB에 얽매인다고 상상해보십시오. 이제 어떤 엔진 도면을 보십니까? 그들 모두 하나? 네 가지가 모두 같은지 어떻게 알 수 있습니까? 아마도 수정이 이루어졌지만 엔진을 1 년 동안 레게 밴드에서 재생하도록 디자인 한 사람이 4 개의 엔진이 별도의 파일에 있다는 것을 기억 한 유일한 사람 이었기 때문에 엔진 1에만 적용됩니다. 폭발 터빈을 수리 한 사람이 그의 교체품이었습니다.

코드 복사 및 붙여 넣기는 나사 또는 엔진이든 구성 요소 부품의 복제 도면과 유사합니다. 최대한 재사용되는 기본 부분으로 구성 요소를 추상화하려고합니다.

엔진을 복제하지 말고 엔진을 날개에 장착하는 코드를 작성하십시오.


11
이제 4 번 엔진이 다른 3 번 엔진과 다르다는 것을 알았습니다. 이 차이가 의도 되었습니까? 이륙 후 즉시 좌회전하여 발생하는 특정 토크 문제에 대응하도록 설계 되었습니까? 아니면 복사 실수입니까?
David Thornley

5
훌륭한 비유 ... 그러나 누군가 복사 / 붙여 넣기 코드를 이해하는 데 어려움이 있다면 ... 제트 엔진은 어려울 수도 있습니다 :)
Steven Evers

이 비유를 위해 제트 엔진 대신 고체 연료 로켓에 대해 이야기해야합니다. 그렇게하면 "로봇 과학 에서처럼?"
detly

이것은 비유가 아닙니다. 블루 프린트는 말 그대로 기계적 인공물을위한 코드입니다.
intuited

7

동일한 리소스를 공유하는 것과 동일한 리소스를 복제하는 것과 관련하여 설명해야합니다.

예를 들어, 대도시의 모든 집이 집에 전기를 공급하는 전용 발전소를 갖는 것이 합리적입니까? 아니면 모든 집이 동일한 발전소를 공유하는 것이 더 합리적입니까? 발전소에서 사용되는 특정 구성 요소에 문제가 발생하여 수리가 필요한 경우 한 곳에서 수리하는 것이 더 쉬울 것이며 모든 전용 발전소에서 수리하는 것보다 모든 사람이 이러한 수리의 혜택을 누릴 수 있습니다. 개별적으로 주택 혜택.


7

" 모든 수술이 다소 비슷해 보이는가? 따라서 수술을 위해 다른 외과의와 다른 절차에 대한 수술 지시 를 무작위로 복사 해도 괜찮 을까?"


1
큰!!! 칼로 수술을 했어요? 정육점 칼을 사용하여 뇌 수술을하겠습니다.
Aditya P

1
@AdityaGameProgrammer : 당신이 가지고있는 유일한 도구가 정육점 칼일 때, 모든 것이 햄처럼 보입니다.
Joey Adams

6

복사 및 붙여 넣기는 금형없이 부품을 제조하는 것과 같습니다. 속도가 느리고 각 부품에서 한 번만 사용할 수 있습니다. 결함이 있거나 파손 된 것으로 판명되면 금형을 수정하여 적절한 교체품을 만들 수 없기 때문입니다.

유추를 찾기 위해 먼저 복사 및 붙여 넣기 프로그래밍 의 위험을 고려해야합니다 .

  • 복사본이 정확하게 맞지 않아서 버그가 발생했습니다 (필수 변수 및 코드 경로가 정리되지 않음)
  • 테스트 요구 사항 증가 — 추상화는 변경 한 내용 만 테스트하고 분기가 아닌 나뭇잎 만 변경하므로 회귀 테스트가 필요하지 않습니다.
  • 복제 는 버그를 포함하여 모든 것을 복제합니다 . 코드의 두 섹션에 모두 적용되는 모든 버그 수정 또는 기능은 이제 구현하는 데 두 배의 비용이 들며 완전히 잊을 가능성이 높습니다.
  • 검색 및 바꾸기는 중복 된 코드를 쉽게 찾을 수 없기 때문에 위의 문제를 악화시킵니다.

복사 및 붙여 넣기 프로그래밍과의 싸움에서 주요 무기는 추상화 입니다. 좋은 유추를 찾으려면 우리 주변의 세계에서 추상화의 예를 찾으십시오.

추상화 는 정의를 설정 한 다음 실행시 해당 정의를 계속 사용한다는 아이디어를 기반으로합니다. 정의없이 세상은 어떻습니까?

  • 정의는 법률 언어의 핵심 부분입니다. 핵심 정의가 없지만 계약이 사용될 때마다 모든 용어를 완전히 정의한 계약을 상상해보십시오.
  • 정의 및 템플릿은 구성에 사용됩니다. 시공에서 흔히 발생하는 문제는 처음에 단일 측정을하는 것이 아니라 마지막을 기준으로 새로운 절단을하는 것입니다. 이로 인해 시간이 지남에 따라 길이가 크게 달라질 수 있습니다.
  • 회사 조직은 초록과 정의를 기반으로합니다. 회사를 확장 할 때마다 새로운 역할을 처음부터 정의해야한다면 어떻게해야할까요? 작동하지 않습니다. 따라서 유사한 직무 역할을 선택하고 해당 업무 역할에 맞게 약간 수정하면 어떻게 될까요? 자원을 옮기는 것은 불가능하기 때문에 모든 사람이 제자리에 고정됩니다.

복사는 복사 할 부분이 영구적 일 때만 가능합니다. 그렇지 않으면, 모든 사본은 완전히 새로운 브랜치가 개별적으로 테스트, 유지 보수 및 업그레이드되도록 처리합니다.

추상화는 모든 가지를 하나의 트렁크에 묶고 작은 가지 또는 나뭇잎에 대한 수정을 분리하여이 문제를 해결합니다.


2
나는 금형 비유를 좋아하고 나머지는 테크가 아닌 사용자에게는 큰 도움이되지 않습니다.
Matthieu M.

@ Matthieu-당신이 첫 번째 글 머리 기호를 언급하고 있는지 모르겠지만, 이것이 유추라고 말하는 것이 아니라 개발자가 좋은 유추를 생각하는 사고 과정이라고 생각하는 것을 설명하고있었습니다.
Nicole

4

붙여 넣기를 복사하지 않고 중복 코드에 대해 이야기하고 있다고 생각합니다 (스 니펫 및 유사 항목 사용).

여기에 역사 책의 비유가 있습니다. 구텐베르크가 출판되기 전에 승려들은 책을 손으로 직접 쓰고 쓰고 같은 책을 계속해서 다시 썼다. 수도사가 쓴 책은 종종 버그가 있었고 구텐베르크 덕분 에이 문제는 제거되었습니다.

또 다른 비유 : 현금 인출기. 다양한 카드를 제공하고 항상 잘 처리 할 수있는 현금 인출기가 하나 있습니다. 코드를 복제하면 다른 현금 인출기가 만들어 지므로 모든 사람이 다른 현금 인출기를 사용해야하고 때로는 기계가 BSOD를 제공하기도합니다.

Jeff http://www.codinghorror.com/blog/2009/04/a-modest-proposal-for-the-copy-and-paste-school-of-code-reuse 에서 복사 붙여 넣기에 관한 멋진 기사가 있습니다. html

추신 : 구텐베르크 이전에 인쇄기가 있었음을 알고 있습니다.


2

프로그래머가 아닌 사람들에게 나는 우리가 비즈니스 사람들과 이야기하고 있다고 가정하므로 간단하고 돈의 현실과 관련이 있습니다.

  1. 모든 코드 라인은 비용이 든다
  2. 모든 버그는 모든 라인보다 훨씬 더 많은 비용이 듭니다.
  3. 모든 코드 줄은 잠재적 인 버그를 추가합니다
  4. 중복 된 코드 = 중복 된 버그
  5. 중복 된 버그는 거의 동일한 테스트주기에서 발견되지 않습니다.

잘라 내기 및 붙여 넣기 = 불타는 돈.


1

질문에 대답 할 수는 없지만 여기서 유추 할 필요는 없으며 각 개발 관용구 나 패턴에 맞는 유추를 찾으려고 노력하는 것은 어리석은 것으로 보이며 종종 생산성이 떨어집니다. 평평한 발로 요가를하는 것과 같습니다 ...

복사 / 붙여 넣기로 인해 문제가 발생하는 데는 몇 가지 이유가 있습니다. 기존 버그를 새로 붙여 넣은 영역으로 전파합니다. 일부 환경에서는 성능 향상으로 여겨졌지만 실제로는 느려졌습니다. 그것은 JIT로 귀결되며 현대 컴파일러보다 똑똑하다고 생각하십니까?).

그것은 개발자가 게 으르거나 이기적이거나 둘 다임을 보여줍니다. 이것이 전투 인 경우, 현재 팀에서 싸우고있는이 팀의 위치 (팀 리더 / jnr dev, snr dev 등)에 따라 가능하면 조직 내에서 조정하여 문제를 해결해야합니다.

편집 : 아래 의견에 비추어, 이것은 제 3 자 (또는 제 4 자 :)를 대신하여 제 3 자 코드를 검토하는 코드입니다) 희망적으로 추가 할 수있는 유용한 것들이 있습니다.

첫째, 제 3 자용으로 코드를 제작할 때 어떤 메트릭이 있습니까? 예를 들어 코드 라인 (LoC).

나는 아직도 내가 위에서 말한 것 중 일부는 여전히 중요하다고 생각합니다. 나는 또한 검토의 목표가 무엇인지 물었을 것이다. 유지 보수를 위해 견적을 받거나 교체하려면 다른 많은 질문을해야합니다.

어느 쪽이든, 당신은 코드 품질을 평가하고 있습니다. 붙여 넣기는 "개발자가 추상화 및 / 또는 프로그램 흐름 제어 설계에 대한 적절한 이해를 보여주었습니다"범주에 속합니다.

주석 : 개발자는 추상화에 대한 이해를 보여주지 못했으며 프로그램 흐름 제어에 대한 접근 방식은 오류가 발생하기 쉽습니다. 여기에서 "Cyclomatic Complex"을 소개 할 수 있습니다. 실제로 이해하는 것은 매우 쉽고, 방법에 대한 라운드에서 대답을 찾았을 것입니다 : D Yay for me.

사이클로 매틱의 복잡성은 다음과 같습니다. 지도가 있습니다. 출발지와 가능한 모든 목적지가 있습니다. 많이 될 필요는 없습니다. 생각, 주차장, 카페, 화장실. 순환 복잡도는 목적지로의 출발 위치에 도달해야하는 다른 경로의 수를 측정 한 것입니다.

복사하여 붙여 넣은 코드는 자체적으로 명명 된 블록 (또는 방법)으로 추상화 될 수있는 반복 된 논리를 포함하기 때문에 순환 복잡성을 증가시킬 수 있습니다.

합리적으로 보입니까?


분명히 이것은 다른 조직이 작성한 코드이며 검토를 위해 조직에 가져 왔습니다. 따라서 그것은 조직 내에서 싸우는 것이 아니라 다른 조직의 사람들 (비 프로그래머)을 이해시키는 데 필요한 것입니다.
EZ Hart

이 정보를 아는 것이 유용하고 희망적으로 유용하게 사용하기가 훨씬 쉽습니다. :) 편집 내용을 추가하겠습니다.
Ian

죄송합니다, 긴 편집이지만 tldr은 복사 및 붙여 넣은 코드는 코드 냄새이며 다른 것들 중에서도 순환 복잡성이 증가 함을 나타내며 순환 복잡성은 단일면 처리되는 은유를 사용하여 설명하기가 매우 쉽습니다.
Ian

1

무언가를 위해 영어 단어를 가져 가라. 이제 그 것을 설명하고 싶을 때마다 단어 대신 완전한 사전 정의를 사용했다고 상상해보십시오. 다른 사람들이 당신을 이해하기가 쉬울까요?

나는 존재하지 않거나 그 경우가 뭔가의 정신적 이미지를 형성 (상상)가 다른 조건으로 인 행동이나 상태를 나타내는; 의지의 단순한 과거. 과거 시간 대비 미래를 나타냅니다. 반복적으로 또는 일반적으로 일어난 과거의 동작을 나타내는 매우 수 (것) 쉬운 일이 아니다; 성취하거나 이해하거나 견디기 위해 많은 육체적 또는 정신적 노력이 요구됨 (어려움).

또한 중복을 제거하기 위해 리팩토링 된 실제 코드의 실제 전후 예제를 보여주는 것이 아프지 않습니다.


Leslie Nielsen 스타일을 전달하기 위해 두 번째 단락을 연습하는 것이 좋습니다 :-)
Karl Bielefeldt

1

보안 및 코드 무결성 문제도 있습니다.

여기설명 된대로 클립 보드로 전송되는 유니 코드 문자로 악성 데이터를 포함 할 수 있습니다.

편집기가 유니 코드 문자에 응답하는 방식에 따라 예기치 않은 소스 코드 변경, 예기치 않은 컴파일러 출력 또는 아직 생각하지 못한 것들이 발생할 수 있습니다.


0

내가 여기에 복용 볼 수있는 몇 가지 다른 경로가 있습니다 :

  1. 표절 -일부는 지적 재산의 절도가 큰 학교에서 이것을 기억할 수 있습니다. 복사-붙여 넣기 프로그래밍은 누군가가 소스를 이해하지 못하거나 맹목적으로 복사하여 붙여 넣은 특정 솔루션을 사용하여 얻을 수있는 문제 와이 작업이 얼마나 잘 수행되는지 분석하지 않고 맹목적으로 복사하여 붙여 넣을 수있는 이유를 이해할 수 있습니다. 문제에 대한 효과적인 해결책.

  2. 맹목적으로 지시를 따름-대부분의 사람들은 이전에는 없었던 곳으로 가야 할 경험이 있었을 것입니다. 일부는 MapQuest 또는 Google지도를 사용하여 장소를 찾은 다음 제공된 지시를 따를 수 있습니다. 사람들이 길을 잃었거나 소프트웨어가 도착하는 방법에 대한 구체적인 지침을 제공했지만 어디로 가야하는지 찾지 못하는 이야기가 있습니다. 복사 붙여 넣기의 또 다른 큰 위험은 여행을 조금 더 어렵게 만들 수있는 지역의지도를 보지 않고 누군가가 A에서 B로가는 길을 건네 준 것과 같습니다. 그것이 어려워 보이지 않으면 A에게 B를 가리고 눈가리개를 착용하도록 요청함으로써 그들이 다른 방향에 의존하여 그들이 향하고있는 방향을 결정하고 목표에 도달하도록 요청함으로써 전리품을 강화할 수 있습니다.

데이터, 정보, 지식 및 지혜 는 복사 및 붙여 넣기가 매우 기계적이고 많은 생각없이 전송 및 전송 된 데이터가 그것을 올바르게 사용하는 지식과 지혜없이. 차이를 이해하는 것이 얼마나 강력 할 수 있는지에 대한 예를 들어 원자력을 살펴볼 수 있습니다. 안전과 관련하여 핵폭탄과 원자로를 대조하고 원자의 힘을 안전하게 활용하기에 충분하지 않은 부분을 아는 방법을 보는 데 사용하십시오.


0

그룹 학생과 학교 규칙이 있다고 가정하십시오. 모든 장소에서 규칙을 게시하는 대신, 모든 학생들은 규칙 사본을 각 사람에게 건네 주어야합니다. 각 학생은 규칙 사본을 반드시 서신에 따라야합니다.

이제 재난의 경우 새 재난 보호소로 가야한다는 규칙 중 하나를 수정하십시오. 각 학생에게 가서 규칙을 수정해야합니다. 학생 중 한 명을 놓치고 토네이도가 맞으면 학생은 옛 장소로 가서 끔찍한 죽음으로 사망합니다.


0

누군가 문서 첨부 파일이 첨부 된 이메일을 보냅니다. 템플릿이 변경 될 때까지 계속 사용하십시오. 걱정하지 마십시오. 새로 고침 된 사본을 보내는 것을 잊지 않습니다.


0

CoCoMo 비용 모델

http://en.wikipedia.org/wiki/COCOMO

적용된 노력 (E) = a * (KLOC) ** b, 여기서 b> 1.0

이 지수 는 코드 줄 수보다 빌드 / 유지 / 지원 / 다시 쓰기 노력이 빠르게 증가한다는 것을 의미 합니다.


0

아무도 아직 고려 맡게이 나쁜 연습에 또 다른 중요한 측면이있다 : 맹목적으로 (다른 사람에서 (전체 또는 부분) 코드를 복사하여 자신의 허가없이이 ) 당신이 파괴 저작권법 수 있습니다 .


0

필자가 본 카피-페이스트 코딩은 개발자가 이해하지 못하거나 자신이하는 일을 추론하기를 원하고, 이미 "더 많거나 적은"일을하는 다른 부분을 함께 복사하여 마지막에 무작위로 흔들리는 것입니다. 그것들을 서로 맞추기 위해.

여기에는 세 가지 주요 문제가 있습니다.

  1. 버그가없는 코드는 발생하지 않습니다. 이제까지.
  2. 코드를 작성하는 동안 코드를 이해하지 못하면 디버깅 중에 코드를 파악할 수 없었습니다. 다른 사람 만이 추가 비용으로 자신이 만든 혼란을 정리할 수 있습니다.
  3. 작성중인 코드에 대해 생각하지 않으면 학습을 피할 수 있습니다. 학습을 피한다면 결코 훌륭한 프로그래머가 될 수 없습니다. 그들이 좋은 프로그래머가되지 않을 것이라면 왜 그들이 당신 팀에 있습니까?

0

당신이 5 명의 여자 친구 (교활한 개)를 가지고 있고 그들 모두에게 발렌타인 데이 메시지를 보내고 싶다고 가정 해 봅시다. 첫 글자를 입력하고, 그녀의 이름을 추가하고, 여러분이 공유 한 기억에 남는 것을 언급하십시오. 그런 다음 문자를 네 번 복사하여 붙여 넣습니다. 매번 오타가 발생했기 때문에 여자 친구 # 1 이름의 인스턴스가 copy and paste로 누락되었습니다. 이제 5 명의 여자 친구 중 4 명이 여자 친구 # 1의 집으로가는 중입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.