»
S
I
D
E
B
A
R
«
권장 리팩터링 순서
October 29th, 2009 by Wegra Lee

최근 다른 사람이 작성한 소스를 리뷰하면서 리팩토링할 일이 있었다. 깊이 있는 리팩토링까지는 해보지 못했으나, 남의 코드 리팩토링은 오랫만이라 간단히 노하우를 정리해본다.

정체를 알 수 없는 임의의 소스 덩어리를 받게 된다면, 대략 아래와 같은 순서로 리팩토링하는 것이 효율적이다.

1. Make duplications

리팩토링의 첫 단계에서는 중복 코드를 생산해낸다. 헐~! 이게 뭔 소린가? 중복 코드를 만드는 데는 조건이 있다. 로직의 상당 부분이 동일 혹은 유사해야 한다.

코드를 살펴보면, 결국 똑같은 혹은 유사한 일을 하면서 따로 노는 모습을 심심치 않게 발견할 수 있다. 각 파트별 담당 개발자가 선호하는 방식이 달라서일 수도 있고, 같은 개발자더라도 나중에 더 나은 API를 찾거나 더 간소한 알고리즘이 떠올랐을 수도 있다. 혹은 전에 짰던 부분과 흡사하다는 걸 떠올리지 못한체 처음부터 다시 짤 경우도 같은 결과가 나타난다.

코드가 척 보기에도 너무 다르다면 눈썰미가 본좌급이거나 운이 좋아야 발견할 수 있다. 따라서 누구나 기계적으로 할 수 있는 방법을 알아보자. 바로 이미 유사한 코드를 찾아서, 동일한 로직으로 만들 수 있는지 보는 것이다. 시장에는 중복 코드를 찾아주는 툴들이 이미 많이 나와있다. 이들 중 더 발전된 것은 유사 코드를 찾아주기도 한다. Java 라면 PMD 나 CheckStyle 같은 툴을 기본으로 사용하고 있으리라 믿는다. 이들 툴의 여러 기능중 duplicated code 검출 기능도 있으니 이를 활용하자. C/C++ 의 경우 언어 한계상 지원 툴이 상당히 빈약한데.. 다행히 위의 PMD 가 C++ 역시 지원해준다. 사용법은 여기를 참조하기 바라며.. 본인도 이를 이용해 작업을 진행하였다. 버그는 좀 보이지만, 간단히 사용하기에는 부족하지 않다.

결과: 같은 일을 처리하는 코드는 모두 동일하게 작성되었다.

2. Remove duplications

다음 단계가 바로 1단계에서 만들어 놓은 (혹은 그 전부터 존재하던) 중복 코드 제거이다. 코드가 중복되어 있다면 리팩토링도 중복으로 해야하고, 각각의 리팩토링 과정을 완전히 동일하게 하기는 상당히 말처럼 쉽지 않다. 중복 코드를 개별적으로 수정하면, 중복된 코드라는 것 자체를 인지하기 어려워진다. 각 코드 블럭의 리팩토링 순간 사이에 시간적 격차가 있으므로, 같은 로직을 보더라도 다르게 리팩토링할 가능성이 생긴다(기계가 아닌 사람인지라). 논리적으로 똑같이 하려해도 human error 가 발생할 여지도 다분하다.

중복 코드 식별 역시 ‘다행히도’ 사람이 하기엔 너무나 벅찬 일이다. 그래서 툴이 필요한데, 1단계에서 사용한 툴들이 바로 그들이다.

결과: 모든 코드는 unique 하다.

(곧 별도의 글을 통해 중복 코드 제거를 위한 몇 가지 패턴은 선보이도록 하겠다.)

3. Remove unused code (variable, code block, method, class, etc)

사용되지 않는 코드는 분석 중 논리 흐름을 방해하며, 자칫 의미 없는 코드를 리팩토링하며 시간을 낭비하게 된다.

대부분 범용 언어는 툴이 잘 지원해주고 있으나, 검출 범위와 사용성은 편차가 좀 있는 편이니 자신의 환경에 접목 가능한 툴들을 한 번 쯤 조사해보는 것을 추천한다.

결과: 모든 코드는 의미를 갖는다.

4. Reformat and rename

코드의 기초 가독성을 높이는 작업이다. 맞춤법에 맞게 코드를 수정하고(reformating), 의미가 명확히 통하는 용어를 사용하게 한다(renaming). Renaming 의 대상은 변수명, (내부) 메서드/클래스명 등이다.

결과: 코드는 의미가 명확한 단위 요소로 구성된다.

5. Refine logic (including extract/inline method)

코드의 논리 흐름을 가다듬는 단계이다. 작문에 비유해보자. 쉬운 용어들을 사용하더라도 산만하거나 애매모호한 글에선 핵심을 찾기 어렵다. 반면 논리 정연한 글은 하고자 하는 바를 쉽게 이해할 수 있다. 따라서 그 논리에 결점이 있다면 바로 파악하여 수정할 수 있고, 논리를 수정하거나, 설명을 보강하는데도 용이하다.

이 과정에서는  이어진 긴 문장을 의미가 분명한 적절한 단위로 나누거나, 큰 문단을 통채로 하나의 추상적 문장으로 교체(extract method)하고, if/else/switch 등으로 복잡해진 흐름을 같은 의미의 더 간결한 논리로 수정하는 등의 작업이 이루어진다. 최종 목표는 주석 없이도 글을 읽듯이 코드를 술술 읽을 수 있도록 하는 것이다.

결과: 코드를 자연스럽게 읽을 수 있다.

Refactoring Home Page 에 가면 수많은 리팩토링 기법들을 찾을 수 있다. 관리자인 Martin Fowler 도 양해를 구하고 있듯이, 설명과 관리에 그리 많은 신경을 쓰고 있진 않지만, 틈틈히 살펴보면 제법 도움이 될 것이다. 내 나름의 기법과 함께 위의 각 단계에서 많이 쓰임직한 것들을 묶어서 정리해보는 것도 재미있을 듯하니, 나중에 시간이 나면 한 번 시도해봐야겠다.


»  Substance: WordPress   »  Style: Ahren Ahimsa