리팩토링(Refactoring)

외부 동작을 바꾸지 않으면서 코드의 내부 구조를 개선하는 기법. 마틴 파울러(Martin Fowler)가 체계화했으며, 익스트림 프로그래밍(XP)의 핵심 실천법 중 하나다.

정의

마틴 파울러는 리팩토링을 두 가지로 정의한다:

핵심은 "외부 동작은 변하지 않는다"는 점이다. 기능 추가나 버그 수정이 아니라, 순수하게 코드의 구조만 개선하는 행위다.

두 개의 모자(Two Hats)

켄트 벡(Kent Beck)이 만든 비유로, 개발할 때 두 가지 모자를 번갈아 쓴다:

모자하는 일하지 않는 일
기능 추가 모자새로운 기능만 추가기존 코드 구조 변경
리팩토링 모자코드 구조만 개선새 기능 추가

한 번에 한 모자만 쓸 수 있지만, 몇 분 간격으로 자주 바꿔 쓴다. 두 활동을 섞으면 실수가 생기기 쉽기 때문에 이 구분이 중요하다.

왜 리팩토링해야 하는가

  1. 설계 개선 — 코드가 시간이 지나며 부패(decay)하는 것을 방지. 중복을 제거하여 구조 유지
  2. 가독성 향상 — 코드를 읽는 사람(미래의 나 포함)이 의도를 빠르게 파악
  3. 버그 감소 — 구조가 명확하면 오류를 발견하기 쉬움
  4. 개발 속도 증대 — 단기적으로는 시간이 들지만, 장기적으로 기능 추가 속도가 빨라짐

[!important] 마틴 파울러의 핵심 주장 리팩토링은 별도 시간을 내서 하는 것이 아니라, 일상적 개발 흐름 속에서 수시로 하는 것이다.

리팩토링 시점

3의 법칙(Rule of Three)

비슷한 코드가 세 번 반복되면 리팩토링할 때다.

네 가지 워크플로우

  1. 준비 리팩토링(Preparatory) — 기능 추가 전에 구조를 먼저 정리. "이 구조로는 새 기능을 넣기 어려우니, 먼저 정리하자"
  2. 이해 리팩토링(Comprehension) — 코드를 읽다가 이해한 바를 코드에 반영. "아, 이 함수가 이런 뜻이구나" → 이름 변경
  3. 쓰레기 줍기(Litter-Pickup) — 코드를 보다가 발견한 작은 문제를 즉시 수정
  4. 계획된 리팩토링(Planned) — 드물게, 오래 방치된 문제를 집중적으로 해결

코드 스멜(Code Smell)

켄트 벡과 마틴 파울러가 대중화한 개념으로, 리팩토링이 필요하다는 신호다.

코드 스멜설명
중복 코드(Duplicated Code)같은 코드가 여러 곳에 존재
긴 함수(Long Method)한 함수가 너무 많은 일을 함
거대한 클래스(Large Class)책임이 너무 많은 클래스
긴 매개변수 목록(Long Parameter List)파라미터가 지나치게 많음
산탄총 수술(Shotgun Surgery)한 변경이 여러 클래스에 영향
기능 편애(Feature Envy)다른 클래스의 데이터를 지나치게 사용

애자일/XP와의 관계

리팩토링은 익스트림 프로그래밍(XP)의 핵심 실천법이다. XP에서 리팩토링은 다른 실천법들과 강하게 연결된다:

YAGNI와 점진적 설계

YAGNI(You Aren't Going to Need It) — 미래를 예측해서 과도하게 설계하기보다, 현재 필요에 집중하고 나중에 리팩토링으로 유연하게 대응하는 점진적 설계(Evolutionary Design) 철학이다.

리팩토링이 뒷받침되면 미래의 변경에 대한 두려움이 줄어든다. "지금 단순하게 만들고, 필요할 때 바꾸면 된다"는 자신감의 근거가 리팩토링이다.

리팩토링을 위한 전제 조건

팀에서 리팩토링을 프로세스화하려면 세 가지가 필요하다:

  1. 테스트 코드 — 리팩토링 전후 동작이 동일한지 검증
  2. 지속적 통합(CI) — 리팩토링 결과가 다른 팀원에게 문제를 일으키는지 빠르게 확인
  3. 리팩토링 문화 — 팀 전체가 리팩토링의 가치를 공유하고 일상적으로 실천

참고 자료

관련 노트