소프트웨어 고고학 (Software Archeology)

By: Beomyong Park

Abstract: 소프트웨어 고고학은 무엇이며 왜 주목해야 하는가? Java Developer's Journal (JDJ) 2008년 1월호에 실린 Mike Rozlog의 특별기고의 번역 번역본입니다.

소프트웨어 고고학(Software Archeology)은 2001년 초부터 다양한 형태로 사용되어 왔다. 소프트웨어 고고학의 개념은 팀원 개인 또는 팀 전체가 사용해야 하는 소스코드 안에 무엇이 있는 가를 정확하게 이해하기 위한 접근법 내지는 방법론이다. 이 접근법은 향후 개발을 위한 디자인 패턴과 개발 패턴을 얻어내기 위해 기존의 소프트웨어를 해체할 때에도 매우 유용하다.

소프트웨어 고고학은 단지 자바에만 관련되지 않고 모든 소프트웨어 언어에서 사용될 수 있다는 것이 가장 멋진 점이다. 이 글은 특별히 자바에만 포커스를 두고 있지만 그 접근법은 거의 모든 유형의 개발 프로젝트에 적용될 수 있다. 오늘날 자바 언어는 매우 성숙하였고 대부분의 새로운 자바 프로젝트는 맨바닥에서 시작되지 않고 오히려 확장과 유지보수에 중점을 두고 있다. 그리고 궁극적인 목표는 현재의 소프트웨어를 더 좋게 만드는 것이다.

소프트웨어 고고학 프로세스는 작업량을 정말로 현저하게 줄여준다. 대부분의 경우에 있어서는 재 작업을 해야 하는 업무를 덜어준다. 프로젝트를 요구 받을 때 모든 개발자가 겪게 되는 어려움은 무엇일까?

  • 내가 방금 인수받은 것은 무엇인가?
  • 어떤 부분이 안전하게 보관되어야 하는가?
  • 코드에서 무시무시한 부분은 어디인가?
  • 어떤 종류의 개발팀이 이것을 만들었는가?
  • 내가 걱정해야 하는 성능 관련 부분은 어디인가?
  • 개발 프로세스 중에 나를 큰 곤경에 처하게 만들 무엇인가가 빠져있는가?

전체적으로 접근법은 6단계 프로세스로 구분된다. 이 프로세스는 무엇이 있고 없는가를 리뷰하면서, 앞으로의 프로젝트 개발 전략을 정의하는데 크게 도움을 준다. 6단계는 다음과 같다:

  • 시각화(Visualization): 어플리케이션 설계에 대한 시각적인 표현
  • 설계 위반(Design Violation): 오브젝트 모델의 건강도를 이해
  • 스타일 위반(Style Violation): 현시점에서의 코드 상태를 이해
  • 비즈니스 로직 리뷰(Business Logic Review): 현존 소스를 테스트할 수 있는 역량
  • 성능 리뷰(Performance Review): 소스 코드에서 병목지점은 어디인가?
  • 문서화(Documentation): 실제 작업해야 하는 사람들이 이해하기에 적당한 문서화가 코드에 있는가?

대부분의 개발자들은 이 단계들을 옙 (YAP, Yet Another Process: 별도의 추가 프로세스)로 간주한다. 하지만 실제로는 이것 대부분은 개발자의 일상적인 프로세스 안에 들어 있어야만 나중에 질릴 정도로 지나치게 과중한 것이 되는 것을 막을 수 있다.

그 다음 질문은 바로 이러한 업무를 수작업으로 할 수 있는가 하는 점이다. 순수하게 기술적인 관점에서는 그렇다. 하지만 오늘날 점점 짧아지는 일정과 계속 높아지는 사용자의 기대를 따라가려면 실제로 이 작업들을 손으로 한다는 것은 시간상 용인되지 못한다.

만약 이것이 수작업으로 될 수 없다면, 이 업무를 해내기 위해 어떤 툴이 필요할까? 자 이제 프로세스를 단계별로 나누어서 각각의 작업을 완수할 수 있는 툴을 살펴보자. 몇몇 고급 IDE는 이 모든 툴을 포함하고 있으며 각 부분을 위한 오픈 소스 기반 툴들도 있다.

소프트웨어 고고학 단지 자바에만 관련되지 않고 모든 소프트웨어 언어에서 사용 수 있다는 것이 가장 멋진 점이다.

** **

시각화(Visualization)는 개발자 자신이 가지고 일을 해야 하는 코드를 이해하는 첫 번째 단계이다. 나는 아직까지 너무나 많은 개발자들이 자신들이 작성한 코드의 시각화를 전혀 본적이 없다는 사실에 놀라곤 한다. 주요 아키텍쳐 이슈의 많은 경우는 단지 시스템의 오브젝트 다이어그램을 살펴보기만 해도 찾아진다. 오브젝트 간의 관계와 상속 레벨 같은 것들은 정말 놀랄만할 것이다. 1,000 줄의 코드보다 한 장의 그림이 낫다는 옛 속담은 진실이다. 자바와 같이 객체 지향 언어의 시각화에는 UML 다이어그램이 주로 사용된다. 최초로 필요한 툴은 코드를 클래스 다이어그램으로 리버스 엔지니어링 하는 것이다. 프로세스 후반으로 갈수록 복잡해지는 클래스와 메소드를 보다 잘 이해하기 위해 시퀀스 다이어그램이나 커뮤니케이션 다이어그램으로 리버스 엔지니어링 할 수 있는 툴이 필요해진다.

일단 시스템에 대한 시각화가 되면 이제 리뷰가 가능하다. 설계 위반 (Design Violation) 관점에서 시스템을 리뷰하는 것 다음 단계이다. 이 것은 정적 코드 지표(metrics)를 사용한다. 메트릭스를 사용하면 개발자 또는 개발팀이 오브젝트 설계의 건강을 체크할 수 있다. 코드 라인 수와 같은 시스템 기본지식 또는 순환 복잡도 (CC, Cyclomatic complexity)와 같이 보다 중요한 지식을 통해 검토자는 많은 정보를 파악한다.

대부분의 개발자는 자신이 작업하는 어플리케이션이 얼마나 큰고 작은지 또는 그 어플리케이션에서 가장 복잡한 부분이 어디인지를 알지 못한다. 몇 개의 메트릭스를 이용하면 개발자들이 “문제”영역을 집어낼 수 있게 된다; 이 영역들은 별도 표시를 해 두었다가 더 깊이 리뷰를 해야 한다. 왜냐하면 일반적인 경우 주로 변경 요청을 받게 되는 부분이 되기 때문이다. 지나치게 복잡하다고 표시된 메소드들은 시퀀스 다이어그램 생성을 통해 심층 분석될 수 있다. 이 다이어그램은 요약된 그래픽 표현을 제공하여 개발자나 관리팀이 해당 메소드를 업데이트하거나 변경하는 작업을 보다 쉽게 이해할 수 있게 한다. 다른 유용한 메트릭스는 제이유닛 테스팅 커버리지 (JUC, JUnit Testing Coverage)이다. 코드를 물려 받을 때 제이유닛 테스트가 없거나 부족하다면 그 시스템을 변경할 때 매우 주의해야만 한다. 가장 큰 걱정거리는 코드에 가해진 변경 또는 오류 수정이 바르게 된 것인지와 혹시 시스템의 다른 부분을 망가뜨리지는 않는 지에 대해 어떻게 보증하는가 하는 점이다.

스타일 위반 (Style violation)은 물려받은 코드에 대한 전체 그림을 완성할 수 있도록 도와 준다. 정적 코드 감사가 먼저 수행되어야 하는가는 개발자들 사이의 논쟁거리이다. 그리고 새 프로젝트의 관점에서 이것은 사실이다. 하지만, 어마어마한 양의 코드를 물려받은 경우 이 메트릭스를 먼저 수행면 오히려 오브젝트 건강 기반에서 보다 많은 정보를 얻을 수 있다. 일단 오브젝트 설계의 건강이 정해지고 상당한 작업을 요하는 코드의 영역들을 집어낼 수 있다면 감사(audit)가 그 지식을 더욱 정제해 준다.

정적 코드 감사는 많은 종류의 규칙 체크를 포함하고 있으므로 코드 일관성, 표준 그리고 나쁜 습관을 찾아 준다. 200여가지의 감사를 포함하는 감사툴은 리뷰 과정에서 어플리케이션의 복잡도를 이해하는데 도움을 준다. 고급 감사툴은 god class, god method, 다른 클래스를 지나치게 애용하게 되는 기능 집착(Feature Envy), 변경 할 때 마다 많은 클래스를 동시에 조금씩 수정해야하는 산탄총 수술(Shotgun surgery) 같은 문제점들을 찾아내는 규칙을 포함하고 있다. 이러한 고급 감사는 실제로 검토자에게 보다 많은 정보를 주기 위해 몇가지 메트릭스를 사용한다. 모든 곳에서 호출되는 클래스에 들어있는 메소드를 뜻하는 God method를 예로 들어 보자. 오브젝트 디자인의 관점에서 이 메소드는 너무나 많은 책임을 가지고 있기 때문에 하나의 메소드 수정이 전체 시스템에 엄청난 영향을 끼칠 수 있음을 의미한다. Feature envy의 경우는 god class와는 거의 정반대이다. 이것은 실제 수행 기능이 거의 없기 때문에 리팩토링을 통해서 이것을 호출하는 클래스 안으로 다시 들어가야 할 수도 있을 것이다. 특정 기능 향상을 하거나 물려받은 코드의 특정 부분의 손대기 위해 소요되는 작업 시간을 산정할 때 이러한 로우 레벨 이해가 유용하다.

비즈니스 로직 리뷰 (Business Logic Review)는 어플리케이션의 시험용이성에 포커스를 둔다. 고급 메트릭스를 이용하면 몇 분만에 테스팅 가용량을 결정지을 수 있다. 많은 양의 코드를 물려받고도 단위 테스트가 없다는 것을 알게 되면 기능향상 견적 시 커다란 영향을 주거나 개발자들이 시스템에 대한 어떠한 변경에 대해서도 검증할 수 없음을 깨닫게 된다. 비즈니스 로직 테스트를 위한 툴은 반드시 코드 커버리지와 제이유닛(JUnit)과 같은 단위 테스트가 통합되어 있어야 한다. 둘 중 하나만 있어도 괜찮다. 하지만 둘 다 있으면 많은 새로운 추가 테스팅을 할 수 있다. 코드 커버리지 툴로 단위 테스트를 실행하여 코드를 검증할 경우, 코드 커버리지는 위에서 논의된 고급 감사 툴과 유사한 기능을 한다. 게다가 좋은 코드 커버리지 툴은 테스트 수행 과정 안에 있는 모든 클래스와 메소드를 보여준다. 산탄총 수술(Shotgun surgery)와 같은 고급 감사를 사용하면 많은 의존관계가 있는 메소드를 강조표시 해준다. 단위 테스팅과 코드 커버리지를 함께 사용한다면 메소드 수정이 완전히 테스트되고 검증됨을 보증할 수 있다. 코드 커버리지 툴의 또 다른 장점은 코드 커버리지를 켜 놓은 채 테스트 스트립트를 실행하는 품질 보증(QA)에서 볼 수 있다. 테스트 스크립트의 완전성 여부와 테스트가 어플리케이션 전체 코드를 커버하는가의 여부를 보여주기 때문이다. 소프트웨어 고고학 중 특히 이 부분은 이것은 일반적으로 점점 좋아지기만 한다는 것이 장점이다.

좋은 프로파일러의 필요성은 성능 리뷰(Performance review)의 핵심이다. 비즈니스 로직 리뷰부터 이 툴을 사용하면 성능 이슈를 발견하고 수정할 수 있다. 명심해야 할 중요 메트릭스는 코드의 약 5%만이 대부분의 성능 이슈를 야기한다는 것이다. 따라서 코드가 복잡한 곳을 관리할 수 있다면 지속되는 유지보수를 더 빠르고 쉽게 할 수 있다는 것을 의미한다.

마지막 단계는 문서화(Documentation)이다. 이것은 개발자, 검토자, 개발팀이 시스템을 이해하는데 대단히 좋다. 만약 그 작업이 지속적으로 수집되고 사용된다면 더욱 좋을 것이다. 자동 문서 생성기는 시간을 절약하고 오버헤드를 줄여주고 문서화가 최신의 것이라는 것을 확신시켜 준다. 이것은 새로 온 팀원 이나 어플리케이션이 다른 팀으로 전달되는 것을 쉽게 해준다.

소프트웨어 고고학의 개념은 매우 단순하다; 이 아티클은 많은 양의 코드를 인수받고 그 코드를 책임지는 것에 대한 접근법을 다루었다. 코드 속으로의 또 다른 탐험은 유용한 디자인 패턴, 재사용을 위한 대단한 알고리즘 또는 피해야 할 주요 점 등을 만들어 낼 수도 있다. 우리 모두는 소프트웨어가 자산이라는 것을 잘 알고 있고 소프트웨어 고고학은 그 투자로부터 최상을 얻어내는 것을 보증한다.

** **

소프트웨어 고고학은 소프트웨어 투자로부터 최상을 얻어내는 것을 보증한다..”

** **

이 글은 JDJ의 2008년 1월호에 실린 Mike Rozlog의 특별기고의 번역 번역본입니다. 원문을 보시려면 다음 url을 참고하세요.

http://www.codegear.com/article/34268/images/34268/software-archeology.pdf

Server Response from: SC2