리팩토링 전략 패턴: 코드 리뷰를 위한 설계 개선

배경

코드 리뷰에서 자주 등장하는 피드백은 “이 코드를 리팩토링해야 한다”는 것이다. 하지만 리팩토링 자체가 목적이 되어서는 안 된다. 리팩토링은 변경의 비용을 낮추고, 가독성을 높이며, 인지 부하를 줄이기 위한 수단이다.

핵심 패턴

1. ‘변경의 방향성’ 패턴

  • 문제: 리팩토링이 무분별하게 이루어져, 오히려 코드의 일관성을 해침.
  • 해결: 리팩토링 전에 ‘변경의 방향성(Direction of Change)’ 을 정의.
    • 예: “이 모듈은 앞으로 확장보다는 안정화가 목표이므로, 인터페이스 변경을 최소화한다.”
  • 리뷰 관점: 리뷰어가 “이 리팩토링이 정의된 방향성에 부합하는가?”를 평가.

2. ‘점진적 리팩토링’ 패턴

  • 문제: 한 번에 큰 리팩토링을 하면, 리뷰가 불가능해지고 버그 발생 확률이 높아짐.
  • 해결: 리팩토링을 작은 단계(Step) 로 나누고, 각 단계를 PR로 분리.
    • 단계 1: 기존 동작을 유지하며 코드 구조 개선 (리팩토링)
    • 단계 2: 기능 추가 (변경)
    • 단계 3: 테스트 보강 (안정화)
  • 리뷰 관점: 각 단계의 PR이 독립적으로 리뷰 가능해야 함.

3. ‘리팩토링 vs 기능 추가’ 분리 패턴

  • 문제: 리팩토링과 기능 추가가 같은 PR에 섞이면, 리뷰어가 혼란스러움.
  • 해결: 절대 리팩토링과 기능 추가를 같은 PR에 넣지 않는다.
    • 리팩토링 PR: 동작 변경 없음 (테스트가 그대로 통과해야 함)
    • 기능 추가 PR: 새로운 동작 추가 (기존 구조를 변경하지 않음)
  • 리뷰 관점: 리뷰어가 “이 PR이 동작을 변경하는가?”를 명확히 알 수 있음.

4. ‘코드 스멜 기반 리팩토링’ 패턴

  • 문제: 리팩토링의 이유가 모호함 (“코드가 마음에 안 들어서”).
  • 해결: 구체적인 코드 스멜(Code Smell) 을 기준으로 리팩토링 결정.
    • 예: “긴 메서드(Long Method)” → 메서드 추출
    • 예: “과도한 매개변수(Long Parameter List)” → 파라미터 객체 도입
    • 예: “샷건 수술(Shotgun Surgery)” → 기능 이동
  • 리뷰 관점: 리뷰어가 코드 스멜을 발견하면, 리팩토링을 요청하는 것이 아니라 “이 코드 스멜이 우리에게 어떤 비용을 초래할까?”를 논의.

통찰: 리팩토링은 ‘기술 부채’가 아니라 ‘인지 부채’를 해결한다

  • 기술 부채(Technical Debt): 코드의 품질이 낮아 미래의 변경 비용이 증가하는 현상.
  • 인지 부채(Cognitive Debt): 코드의 복잡도가 높아, 이해하고 변경하는 데 드는 인지적 비용이 증가하는 현상.
  • 핵심: 리팩토링의 진정한 목적은 기술 부채보다 인지 부채를 줄이는 것이다. 코드가 아무리 ‘깨끗해’도, 이해하기 어려우면 리뷰와 유지보수가 어렵다.

연결된 개념