소스 코드 복사의 위험성

Posted at 2007.02.28 20:22 // in S/W개발 // by 김윤수


S/W 개발 프로젝트를 진행하다 보면 통곡할 일이 벌어지곤하는데, 이름하여 "코드를 복사해서 재사용하기" 현상입니다. 이런 일들을 자주 보고서는 소스 코드 복사가 얼마나 위험한 행동인지 빨리 얘기해야 되겠다 싶어 급한 마음에 키보드 두드려 봅니다.

소프트웨어 공학에서 오랜 기간 재사용 재사용을 외쳐 왔지만, 현장에서 가장 잘 사용되는 형태의 재사용은 코드를 복사해서 재사용하기겠죠. 특히 프로젝트 일정이 바쁘면 가장 잘 나타나는 개발자들의 나쁜 버릇 중의 하나입니다. 항간에는 "코드를 복사해서 재사용하기" 초식을 후배들에게 마치 고수의 초식인냥 진지하게 전수해 주는 선배들이 있다는 소문이 들려 오니 더 난감할 따름입니다. 이 초식을 쓰는 사람은 머지 않아 주화입마에 빠져 "걸레 코드 디버깅하기", "디버깅한 코드 또 디버깅하기", "Defect 리스트 계속 불어나기" 등등에서 헤어 나오지 못하는 무서운 초식임에도 이렇게 무분별하게 전수된다 하니 이제 쌍수를 들어 말려야 겠습니다.

그렇다면, 제가 왜 그렇게 "코드를 복사해서 재사용하기"를 그렇게 나쁘다고 할까요 ? 제가 재사용을 싫어하기 때문일까요 ? 설마~ 제가 그런 이상한 사람일리가 있나요. 얼마전부터 S/W 업계에서 재사용이 중요하다며 난리 부루스를 추는 상황에서 재사용을 반대할 리가 있겠습니까? 제가 반대하는 것은 "코드를 복사해서" 재사용하기를 반대하는 겁니다.

자~ 여러분이 S/W 개발 도중에 다음과 같은 코드를 짜게 되었다고 합시다.

void functionA(char msg[]) /* 다른 argument 도 있다고 칩니다 */
{
  char buf[128];
  sprintf(buf, "%s::%d::%s ", __FILE__, __LINE__, __FUNCTION__);
  strcat(buf, msg);
  fprintf(stdout, buf);
  ......                   /* 이 함수에서 해야할 일을 합니다. */
}


그리고 나서, 다른 함수를 작성하다 보니 비슷한 일을 할 필요가 있었습니다. 그래서, 다음과 같이 위 코드를 복사해다가 넣습니다.

void functionB(char msg[]) /* 다른 argument 도 있다고 칩니다 */
{
  char buf[128];
  sprintf(buf, "%s::%d::%s ", __FILE__, __LINE__, __FUNCTION__);
  strcat(buf, msg);
  fprintf(stdout, buf);
  ......                   /* 이 함수에서 해야할 일을 합니다. */
}


그리고, 개발이 진전됨에 따라 또 다른 함수 functionC(), functionD(), ... 이렇게 위 코드를 복사해서 쓰는 코드는 갈 수록 늘어갑니다. 설상 가상으로 여러분 후배 또는 동료가 위 코드를 보더니, 쓸만하다 싶어 또 복사해다가 씁니다. 개발하는 동안 이런 저런 테스트를 무사히 통과합니다. 시스템 테스트 단계까지 다 거쳐서 패키징된 후 시장에 드디어 입성했습니다. 아니 그런데 이게 웬 일입니까 ? 테스트할 때는 아무런 문제가 없던 코드가 시장에 나가서 고객들이 쓰기 시작하더니 하루가 멀다하고 리콜이 들어옵니다.

비상 회의 소집되고, 몇 일에 걸쳐 문제를 찾고 또 찾고 갔더니 위 코드에 문제가 있다는 걸 겨우 알아냈습니다. 그래서 functionA()를 다음과 같이 수정했습니다.

#define BUF_SZ 256

void functionA(char msg[])
{
  char buf[BUF_SZ];
  int nr;
  /* buffer overflow를 막기 위해 sprintf, strcat 대신 snprintf 및
     strncat을 사용합니다 */
  nr = snprintf(buf, BUF_SZ-1, "%s::%d::%s ",
    __FILE__, __LINE__, __FUNCTION__);
  strncat(buf, msg, (BUF_SZ-1-nr >= 0 ? BUF_SZ-1-nr : 0));
  buf[BUF_SZ-1] = '\0';  /* buffer 가 다 찬 경우-BUF_SZ-1개 만큼-에는
                          * 마지막 '\0'가 채워져 있지 않으므로 */
  fprintf(stdout, buf);
  ......                 /* 이 함수에서 해야할 일을 합니다. */
}


그리고, 다시 테스트해 봤더니 functionB()에도 복사한 코드가 문제가 있다는 걸 발견합니다. 개발하는 동안 위 코드를 몇 번 복사했다는 걸 생각해 내고는 생각나는 곳은 다 고칩니다. 그런데 이게 또 무슨 운명의 장난이란 말입니까? functionD()에도 해당하는 코드를 복사해서 썼다는 것을 깜빡한 것입니다. 이런 저런 테스트를 하는 동안 문제가 없이 통과해서, 이번에는 문제가 없을 거라며 큰소리 뻥뻥 쳐가면서 이미지를 릴리즈합니다.

아니 웬 걸. 몇 달 안가서 또 비슷한 문제가 터집니다. 입에서 'ㅆ' 욕이 막 나옵니다. 이번에도 죽을 똥 쌀 똥 피똥 다 싸가며 겨우 문제가 되는 지점을 알아 냈더니 결국 functionD()에서 복사한 코드를 고치지 않았단 것을 알아냅니다. 누굴 탓하겠습니까? 복사한 자기를 탓해야지요. 이리하여 이 제품의 코드는 안정화되고 그럭저럭 시간이 지나갑니다.

새해가 돼서, 이전 코드를 기반으로 새로운 파생 제품을 만든다고 합니다. 그런데, 이번에는 OS와 컴파일러가 달라진다네요. 별 문제 없겠거니 하면서 Target OS와 컴파일러에서 컴파일을 하려고 했더니, 이전 OS와 컴파일러에서는 잘도 컴파일 되던 게, 화면에 엄청난 에러 메시지를 내뱉으면서 컴파일이 중단됩니다. 그 엄청난 컴파일 에러 메시지들을 일일이 찾아 봤더니, __FUNCTION__ 이라는 predefined macro를 모르겠다며 난리를 치는 것입니다. 어이구 내 팔자야~ 내 자식들은 절대 기술자 못되게 한다고 몇 번씩 다짐하면서 컴파일 에러 난 곳을 일일이 찾아다니며, __FUNCTION__ macro를 쓰지 않는 것으로 다 수정합니다. 수정하는 동안 제품단가를 줄이기 위해 Target OS와 컴파일러를 수정하자고 한 상품기획팀만 내내 욕합니다.

어떻습니까? 이제 감이 잡히십니까? "코드 복사해서 재사용하기"의 가장 큰 문제는 원래 코드의 문제가 복사되는 곳에 계속해서 퍼진다는 것입니다. 물론 원래 코드에 전혀 문제가 없다면 뭐~ 괜찮겠지요. 그렇지만 위에서 복사됐던 코드도 잘 뜯어보면 몇 줄 되지 않은 코드에 상당히 많은 버그를 품고 있습니다-주로 buffer overflow. 그래서 결국 한 번 수정으로 해결할 수 있는 문제를 n 번 수정이 필요한 문제로 만들어 버린다는 거죠. 단순 수정이라면 그나마 괜찮지만, 수정을 위해 그 이전에 필요한 단계-재현, 원인 분석 등-를 생각하면 그 비용은 어마어마한 차이가 있을 것입니다.

그러니 제발~ 여러분이 만약 어떤 코드를 반복적으로 복사해서 재사용하고 있는 걸 발견하시면, *두말 없이* *바로* 그 코드를 함수 또는 상위 클래스의 메소드-성능이 문제라면 inline 함수 또는 macro 함수-로 만들고, 그 함수를 호출하는 식으로 바꾸셔야 합니다. 그리고, 여러분이 짠 함수가 공통적으로 여러 모듈에서 사용될 수 있겠다는 생각이 들면, 팀원들에게 공지 한 번 해서 이러이러한 함수 또는 클래스 만들었으니 다 같이 잘 써보자. 문제가 있으면 알려달라 이렇게 해야 합니다. 물론 상세 설계 단계에서 제대로 설계했더라면 구현 단계에서 이런 일을 할 필요는 없겠지만, 뭐~ 아직 우리 내공이 상세설계를 그 정도까지 잘하지 못하는 게 현실 아닙니까 ? 구현단계에서라도 잘 해야죠.

"코드 복사해서 재사용하기" 만행은 꼭 한 함수 또는 짧은 코드를 대상으로만 이뤄지는 게 아닙니다. 어느 정도 큰 모듈(또는 컴포넌트) 전체의 소스코드를 "복사해서" 재사용하기도 합니다. 이것도 마찬가지로 짧은 코드를 복사할 경우랑 똑같은 문제가 있습니다. 원래 모듈에 있던 문제가 복사해서 쓰는 곳에 계속해서 퍼진다는 것입니다. 만약 해당 모듈을 참조해서 쓴다면-예를 들어, 복사된 소스코드를 직접 컴파일해서 library를 만들지 않고, 해당 모듈의 소스코드 중 헤더파일만 쓰고, library는 해당 모듈이 build 되는 위치로 링크해서 쓰는 경우-원래 소스코드를 수정한 후, 해당 library만 update 하면 문제가 없을 것입니다. 한 가지 예를 들어 보죠. 이름하여 CMW(Common MiddleWare)라는 모듈이 있다고 칩시다. 이 Middleware를 여러 application에서 쓸 수 있는 핵심적인 공통 기능을 구현해 놓고 있어서 상당히 많은 application이 쓴다고 가정해 봅시다. 그리고, 각 application들-A, B, C-은 서로 별도의 프로젝트로 진행되고 있다고 생각해 봅시다.



서로 다른 application의 소스코드 관리자는 다음과 같이 build tree를 만들 수 있을 겁니다.

A--+- include
     |
     +- lib
     |
     +- src
     |
     +- cmw --+- include
              |
              +- lib
              |
              +- src

B--+- include
     |
     +- lib
     |
     +- src
     |
     +- cmw --+- include
              |
              +- lib
              |
              +- src

C--+- include
     |
     +- lib
     |
     +- src
     |
     +- cmw --+- include
              |
              +- lib
              |
              +- src

위와 같은 상황에서 cmw의 버그를 수정했다면 cmw 소스코드를 각 application 소스코드 관리자에게 릴리즈하고, 각 application 소스코드 관리자는 직접 cmw 의 변경 사항을 적용해야 할 것입니다. 소스코드 관리툴이라도 쓰고 있으면, 이런 과정은 더 복잡해집니다. application A 소스코드 관리자는 새로운 릴리즈를 잘 적용해서 문제를 해결해 놓았는데, B,C 소스코드 관리자는 실수로 해당 변경을 적용해 놓지 않았다면 어떻게 될까요 ? B와 C는 계속해서 문제점을 안고 있을 것입니다. 나중에 시스템 테스트를 하는 동안 문제가 발견된다면 또 B 개발자 C 개발자는 한참 시간을 허비한 후에야 CMW의 문제였다는 것을 알고 허탈해 할 것입니다.

만약 위와 같은 소스코드 트리를 다음과 같이 바꾼다면 어떻게 될까요 ?

CMW --+- include
      |
      +- lib
      |
      +- src

A--+- include
   |
   +- lib
   |
   +- src

B--+- include
   |
   +- lib
   |
   +- src

C--+- include
   |
   +- lib
   |
   +- src

각, A,B,C application 에서는 CMW를 참조만 하고, 소스코드를 복사하지 않는다면 CMW의 update를 A,B,C 에서는 바로 사용할 수 있게 될 것입니다.

물론, 위와 같이 특정 모듈을 공통의 소스코드 repository로부터 사용할 수 있는 경우는 소스코드를 하나의 조직에서 관리할 경우에 쉽게 가능할 것입니다. 만약 소스코드 관리 권한이 여러 조직에 흩어져 있다면-예를 들어, application A,B,C를 서로 다른 조직에서 개발한다면-어쩔 수 없이 소스코드를 복사해서 써야 하는 경우도 있을 것입니다. 그리고 해당 모듈을 사용하는 조직에서 너무 잦은 업그레이드를 원하지 않을 경우도 있을 수 있구요. 그러나, 소스코드 관리 권한이 흩어져 있는 경우라 하더라도 먼저는 소스코드를 복사하기 보다는 참조해서 쓸 수 있는 방법은 없나를 고민해 봐야 할 것입니다. 예를 들어, ClearCase 에서는 Multi-Site 기능을 활용한다던지, CVS에서는 rsync를 이용해서 원격 소스코드 repository 간에 동기를 맞추어주고, 이용하는 쪽에서는 소스코드 변경을 가하지 못하도록 하는 것도 생각해 볼 수 있을 것입니다. 아니면 소스코드를 복사하되, 참조용으로만 사용하고, 변경은 허용하지 않는 경우도 있을 것입니다-물론 이 경우는 시스템 상으로 막히는 것이 아니기 때문에 문제가 발생할 소지가 커집니다.

서로 다른 조직에서 모듈의 소스를 복사해서 재사용하는 경우에 또 다른 문제로는 유지보수 문제가 있습니다. 복사해서 사용하는 측에서 문제점을 발견하여 수정하더라도 원래의 소스코드에는 해당 문제를 수정한 내용이 반영되지 않는 다는 점입니다. 서로 다른 조직이 각각 문제를 해결해가면서 유지보수를 해감으로써 유지보수 비용이 n 배가 될 수 있습니다. 게다가 해당 모듈을 각 조직이 유지보수해 가면서 전혀 다른 소스코드로 발전해 가면서 서로 호환되지 않게 되는 문제도 발생하게 될 것입니다.

따라서, 서로 다른 조직간에도 모듈을 재사용할 경우, 복사해서 사용할 것인지는 소스코드의 관리 측면에서 충분히 검토한 후에 결정해야할 것입니다.

쓰다 보니 말이 길어졌네요. 결국 제가 하고 싶은 말은 한 가지입니다.

"웬만하면 소스코드 복사해서 재사용하지 맙시다"

그럼 여러분께 마지막으로 숙제하나 내고, 글을 마칠까 합니다.

Open Source를 재사용하는 프로젝트에서 소스코드 트리에 Open Source를 Import 시켜야할까요 말아야 할까요 ? Open Source 코드 자체 수정이 필요한 경우와 단순 재사용하는 경우를 구분해서 생각해 보시기 바랍니다

소프트웨어 관련된 저의 다른 글들도 참고로 읽어 보세요.

소프트웨어는 soft 해야 제 맛이다
Flexible한 S/W 작성하기
소스코드 복사의 위험성
C++ 이야기 첫번째: auto_ptr 템플릿 클래스 소개
C++ 이야기 두번째: auto_ptr의 두 얼굴
C++ 이야기 세번째: new와 delete
C++ 이야기 네번째: boost::shared_ptr 소개
C++ 이야기 다섯번째: 내 객체 복사하지마!
C++ 이야기 여섯번째: 기본기 다지기(bool타입에 관하여)

Daum 블로거뉴스
블로거뉴스에서 이 포스트를 추천해주세요.


신고
  1. 이전 댓글 더보기
  2. oseb

    2007.02.28 18:50 신고 [수정/삭제] [답글]

    앞으론 요약 좀 해 주세요. dc인사이트 같은 곳은 3줄 요약 같은데 유행이던데...

    여담인데, *nix에서는 copy&paste가 x-window에 기본으로 활성화되어 있어서 그 작업이 무척 편하던데 전 그게 제일 먼저 떠 올랐습니다. 그리고 아직 strncat/strncpy 같은 함수는 gnu glibc에는 포함되지 않았더군요.

    문서에 스타일이라는게 생겼고 같은 개념으로 웹문서에도 스타일시트가 생겼죠. 옛날에 문서 한 부분에 명조체 14포인트를 적용했는데 그게 마음에 들어서 각 중간 제목은 모두 그렇게 수작업으로 바꾸었는데 결재 도중에 고딕체 13으로 해라는 지시가 떨어져서 일일이 수작업으로 바꿔야 했던 시절이 생각나네요. 그 이후론 스타일 적용해서 그 스타일 값만 바꾸면 한번에 바뀌니 편해졌지만요. 코딩도 그런 공통 함수는 잘 만들어 놓아야 할 듯 싶습니다. 특히 공동작업에서는 좀 엄격해져야 할 필요는 있을 것 같습니다.

    처음에 소스코드 복사라고 해서 OOP 재활용이라 생각하고 들어왔더니 그 얘기가 아니네요. 이건 일종의 탬플릿처럼 함수 자체를 재활용 하는 거네요. ;) 아무튼 서로 호흡 잘 맞추어서 예상치 못한 일 덜 일어나도록 하는 방향이 합리적이겠죠. 어제 모 블로그에 f-22 일본으로 배치하러 갔다가 날자변경선에서 시스템에러로 위기 모면하고 빠꾸했다는 글보고 이 글도 보니 묘하네요.

    • 김윤수

      2007.02.28 19:16 신고 [수정/삭제]

      제목에서 제 글의 내용을 함축적으로 표현해 보려고 노력하는 게 항상 제 원칙인데... oseb 님께는 예상과 빗나간 내용이었나 봅니다. 메타 블로그에 3~4 정도 앞부분이 나오니까 앞에 요약된 내용을 써 달라는 뜻으로 이해해도 되나요 ? 첫부분을 약간 수정 보완해 봤습니다.
      소스 코드 복사의 문제는 다른 곳에서도 비슷하게 많이 발생할 것 같습니다. 코멘트 감사합니다.

    • -_-

      2007.02.28 22:48 신고 [수정/삭제]

      요약은 니가 해서 읽으세요.
      밥상 차려놨으면 됐지 쌈까지 싸서 떠먹여 드려야 됩니까?

    • 김윤수

      2007.02.28 23:04 신고 [수정/삭제]

      답변을 약간 감정적으로 하셨네요. 참... 곤란하게시리... 허~ ^^;

  3. Lawhacker

    2007.02.28 18:55 신고 [수정/삭제] [답글]

    좋은 글 잘 읽고 갑니다.
    즐거운 휴일 보내세요..^^

  4. monaca

    2007.02.28 19:16 신고 [수정/삭제] [답글]

    이를 오래전부터 코드 오염이라고 표현했습니다. 중복된 코드의 전파는 코드 오염 확장이겠지요. bottom-up 설계시에 코드 오염을 최소화하는 코드를 작성하면 잘 설계된 라이브러리가 나오게 됩니다. 이런 라이브러리들은 대부분 비슷한 방법과 설계를 보이게 되는 데, 이는 우연이 아니죠. 이런 bottom-up 설계를 바탕으로 top-down 설계도 가능합니다. 경험이 없는데 top-down 설계는 안된다고 생각하고, 가장 이상형은 이 둘간의 절충형이라 생각합니다. 코드오염을 최소화하는 방향으로 코드를 작성하고, 리팩터링을 반복하면 좋은 설계가 나옵니다. 문자열 처리는 극단적으로 ss_strncpy() 함수를 정의하고 C 컴파일러에 따라 실제 호출되는 함수를 다르게 하는 방식도 가능합니다. 일종의 wrapper routine을 두면 나중에 코드 수정을 적게 합니다. 이는 코드 오염을 막고, 잘못된 코드가 전파되는 것을 막기 위한 것입니다. 또 하나의 문제는 짝프로그래밍을 하거나 멘토가 되어서 다른 사람의 코드에서 strcpy(), strncpy() 등을 썼다면 ss_strncpy()를 쓰게 하는 것처럼 라이브러리 사용을 적극적으로 전파하는 과정이 필요합니다. 코멘트가 길어졌군요.

  5. 인포랩

    2007.02.28 19:38 신고 [수정/삭제] [답글]

    복사 등 차용해서 쓰는 코드들은 아무래도..
    자신이 아무리 뒤적여서 꼼꼼하게 본다 하더라도..
    본인이 직쩝 짠 것과 다를 듯 하네요.
    아무리 코드가 길어지고 복잡해져도..
    본인이 처음부터 다 작성한거면... 대개 잘 찾아내고..
    정정도 정확하고 빠른 듯..
    코드를 빌려쓰거나 마구 짜집기하게 되면...
    교정은 더더욱 어려워지는 듯 하네요.
    예전에 솔루션 하나 -_ - 공개 소스로 마구 뜯어놨다가..
    쌩고생하곤.. 처음부터 결국 다시 손수 하던 격이...
    어디까지나.. 공개나 카피는..
    분석해보고.. 참고로 하고.. 아이디어 획득하거나 하는건 몰라도
    그대로 써버리는건 두고 두고 문제인 듯 합니다.
    남의 성과를 마구 끌어다쓴다는 문제도 있고..
    그걸 교정하거나 개정 추가하는데도 엄청 어려운..

  6. 신희섭

    2007.02.28 20:03 신고 [수정/삭제] [답글]

    헉. 김책임님 ^^
    올블로그 IT/과학 분야 추천글에서 김책임님의 글을 보게 될 줄이야...
    그간 블로그를 하신다는 얘기는 얼핏 들어 알고 있었는데, "그" 블로그를 실제 방문하게 되다니 영광입니다.
    회사밖 온라인에서 뵈니 더욱 반갑습니다.
    그럼...

  7. 기수열외

    2007.02.28 21:26 신고 [수정/삭제] [답글]

    헉...무슨말인지 하나도 모르겠다는..
    역시 인문학부는 안되는가...OTL
    그래도 잘 읽고 갑니다~(결론은 소스 코드 복사하지 말자는 말 맞죠?ㅡㅡ;;)

    • 김윤수

      2007.02.28 21:54 신고 [수정/삭제]

      아직 제가 일반인들이 이해할 수 있을 정도로 쉽게 글을 쓰진 못하는 것 같습니다. 일단 컴퓨터에서 문서 작업하고 비교해 본다면... 어떤 그림을 그려 놓았는데, 그 그림이 쓰이는 곳이 많아서 이 문서 저 문서에 삽입해 놓았다고 가정해 보시죠. 근데 그 그림이 잘못됐다는 걸 알고 수정해야 한다면 어떻게 될까요 ? 이 문서 저 문서를 다 열어서 고쳐야 되겠지요. 근데 만약 그림을 삽입하지 않고 링크만 걸어 놓았다면 어떻게 될까요 ? 일일이 찾아 다니지 않고 원본만 고치면 될 것입니다. 코드 복사는 문서에 그림을 삽입하는 경우와 같다고 생각하시면 됩니다.

    • 엔아

      2007.02.28 23:54 신고 [수정/삭제]

      재사용하셔도 되요...
      완벽하게 컨트롤 하실수 있으시다면....
      그게 맘처럼 되지 않고 그소스 만들고 그회사에 평생있는게 아니니 안쓰는게 좋다는 얘기지요..
      사람은 망각의 동물... 이였던가요..

  8. 허준회

    2007.02.28 22:11 신고 [수정/삭제] [답글]

    안녕하세요~ 올블로그에서 이름 보고 들어왔습니다.
    반갑습니다. 여기서도 좋은글을 올리시는군요.. 자주 찾아뵙겠습니다~

  9. oseb

    2007.03.01 02:01 신고 [수정/삭제] [답글]

    위에 추가 댓글기능이 작동 안해서 여기 추가 합니다.

    #
    -_-
    2007/03/01 15:48
    댓글 주소 수정/삭제
    요약은 니가 해서 읽으세요.
    밥상 차려놨으면 됐지 쌈까지 싸서 떠먹여 드려야 됩니까?

    요약해 달라는 말이 많이 불편했나요? 진담반 농담반으로 한 것 맞습니다. 이모티콘을 넣으서 끝에 웃는 얼굴을 넣었으야 했는데 앞으로 참고하겠습니다. 글에 화내는 내용인지 아닌지 구분을 못한 사람이 잘못했네요.

    김윤수님, 혹시 제 글로 오해가 생겼다면 미안하게 됐습니다. 댓글이 많은 것을 보니 어디 메타블로그에 링크된 모양인데 거북하게 할 생각이 없었다는 것을 이해해 주세요. 그럼.

    • 김윤수

      2007.03.01 03:01 신고 [수정/삭제]

      오해하진 않았습니다. 다만 댓글을 다신 분이 조금 과민하게 반응해서 제가 더 죄송하네요. 요약은 니가해서 읽은세요는 제가 쓴 댓글이 아닙니다. 오해 없으셨으면 좋겠네요.

  10. daewonyoon

    2007.03.01 03:02 신고 [수정/삭제] [답글]

    급하게 결과를 보여야 할 때는 비슷한 부분을 복사해서 만들어서 쓰게 되는 것 같습니다.

    기존에 있던 부분을 새로 만드는 부분에 적용하려면, 인터페이스라던가 그런 부분을 같이 고쳐주어야 할 경우도 있죠. 어떻게 인터페이스를 고쳐줘야 하는지 고민을 하기가 귀찮고, 바꾸겠다고 결정한다고 해도, 이 경우엔 이번에 새로 들어가는 부분뿐 아니라, 복사하려는 함수가 이미 쓰이는 부분까지 몽땅 찾아다니며 고쳐줘야 할 테고, 그 부분에 대한 테스트까지 이루어져야 할 터인데, 이게 머리아픕니다.

    그래서 나중에 보면, 한숨만 나오는 코드가 만들어 지죠. 이걸 언젠간 고쳐야 할텐데 생각은 들겠지면, 일단 문제없이 돌아가는 동안은 잊어먹게 되고요. 결국 비슷비슷한 게 여러개 있는 보기싫은 코드가 되죠.

    • 김윤수

      2007.03.01 03:11 신고 [수정/삭제]

      맞습니다. 급하게 하는 게 문제입니다. 급할 수록 돌아가는 말도 있지만 실제 하다보면 그게 정말 어렵죠. 언제나 개발자들이 정말 깊이 생각해 가면서 개발할 수 있는 환경이 만들어질지...

  11. 마루

    2007.03.02 00:03 신고 [수정/삭제] [답글]

    개발자에게 경종을 울리는 좋은 포스팅인것 같습니다.
    쉽게 갈려다 어려운 난곡에 빠진다는 진리를 깨우쳐주려는 뜻인것 같습니다.
    한 두번이야 괜챦을지 모르나 누적되고 연장이 되면 나중에는 전체를 다 뒤집어야 하는 엄청난 시련을 맞이 할수도 있다는 것...
    많은 분들이 새겨들었으면 하는 바램입니다.

  12. 미디어몹

    2007.03.02 01:02 신고 [수정/삭제] [답글]

    김윤수 회원님의 상기 포스트가 미디어몹 메인에 링크되었습니다.

  13. ENTClic

    2007.03.02 05:39 신고 [수정/삭제] [답글]

    개발자는 아니지만 정말 동감하는 글입니다.
    개발하시는 분들이 어떤 방법을 보편적으로 사용하는지 전 잘 모르지만 제 생각에도 그저 복사/붙이기는 만들기 쉽고 편할지는 몰라도 훗날 개편을 한다거나 수정이 필요할때는 엄청난 난관에 걸릴 가능성이 많을 것 같군요.

    좋은 글 잘읽었습니다^^

  14. bluewing

    2007.03.02 08:46 신고 [수정/삭제] [답글]

    문제는 그렇게 하고 넘어가야할 상황이 생길때가 있다는 거죠.
    함수 한개의 소스코드 라인수가 1000라인이 되는걸 고쳐야 했던적이 있습니다.

    문제는 함수가 호출되는 경우의 수가 확실치 않았다는거. 파라미터로 Object배열을 받는데, 배열의 수가 30을 넘습니다. 이건 도저히.... 각 Object에 어떤 타입의 어떤 값이 들어올지 명세도 없고.. 18 조또.....

    결국 전체적인 로직 파악도 안돼서 함수를 복사해놓고는 부분만 고쳐놓고 나왔습니다. 규모있는 SI기업이라는 곳에서 소위 6개월 량산형 프로그래머들 동원해서 일단 만들어만 놓은 시스템이었죠. 하위 협력회사이다보니 그걸 커스터마이징했어야 하는건데.... 1000라인짜리 함수만드는 삽질을 대단하고 자랑스러운걸로 생각하는 그들을 바라보면서 들었던 여러가지 복잡한 생각들.. 가비지 인, 가비지 아웃.

  15. 흑룡

    2007.03.02 17:49 신고 [수정/삭제] [답글]

    더 중요한 원인은 시간과 인력같은 자원의 문제가 아닐까요.

    왠지 개발을 그냥 하면 된다고 생각하는 윗분들 때문에(그분들이 옛날에 그렇게 해 와서인지) 제대로 생각하고 여러가지를 고려해서 짤 시간과 인력을 안주는게 문제가 아닐까 하네요.

    • 김윤수

      2007.03.02 17:58 신고 [수정/삭제]

      그것도 문제이지만, 복사의 위험성을 모르는 개발자들이 많다는 것도 문제입니다. 복사가 좋지 않다는 것은 주로 경험에서 얻어지는 것이죠. 물론 말씀하신 대로 시간&인력도 문제이긴 하지만 제 생각으로는 복사가 위험하다는 걸 잘 모르는 게 더 큰 문제인 것 같습니다.

  16. 콩자반

    2007.03.03 03:12 신고 [수정/삭제] [답글]

    저같은 경우, Copy해서 같은 기능을 구현하고 싶을 때 우선 그 함수를 좀더 "Refectoring"합니다. 나눌수 있을 만큼 나누고 , 용도가 변경되더라도 그 특유의 기능을 살리도록 , 이름명칭 하나도 고민고민해서 만들어 봅니다. 그 후 나중에 이러한 유용한 함수들을 묶어서 자신만의 Utility 란 Library를 만들지요.

    가령 장기 프로젝트 할때, 자신이 만든 소스를 자신이 필요할 경우도 이런식의 방법으로 재사용하지 않으면, Mr.Garbage만 좋아하는 맛있는 스파게티가 되는 것이지요.

    동의합니다. 이제는 좋은 제안이 모아져 "올바른소스재사용법"이란 좋은 Article이 필요한 시기인가 봅니다. 좋은 문제 재기입니다.

    ps. 왜 뎃글에 들여쓰기가 불가능한것인지.^^;

  17. 뇨릉

    2010.07.07 21:01 신고 [수정/삭제] [답글]

    소스코드 중복에 대한 검색을해보다가 들렸는데요. 글이 작성된지 3년이 지나서 읽게 되었네요 ㅎ

    이 글을 읽으면서 소스코드중복에 관련 생각이 떠올른게 있는데요.
    저도 코드중복과 관련해서 제품의 커스터마이징작업관련된 내용으로 포스팅을 .한번해봐야겠습니다^^ㅋ

  18. Warning

    2012.06.20 04:39 신고 [수정/삭제] [답글]

    좋은글, 감사합니다! 제블로그로 퍼가겠습니다 ㅠㅠ

  19. 휘리

    2012.07.19 00:24 신고 [수정/삭제] [답글]

    좋은 글이네요~ 초보개발자인데 도움이 많이 되었습니다!!

  20. 따뜻한 정원

    2017.10.19 06:08 신고 [수정/삭제] [답글]

    제가 소스코드 복제에 관한 생각들을 수집하고 있는데, 제 블로그에 링크만 퍼갔는데 혹시 불편하시면 바로 삭제 할게요.....
    http://warmgreen.tistory.com/

댓글을 남겨주세요.