1. TDD 리팩토링: 가장 일반적인 리팩토링이다. (1) 테스트를 만들고 (2) 성공시키고 (3) 리팩토링한다. 테스트가 먼저 필요하다. 리팩토링을 할 때 실수하지 않기 위해서다. 기능 개발과 리팩토링은 분리해서 작업한다. 기능 개발과 리팩토링 작업을 빠르게 오갈 수 있지만, 자신이 어떤 작업을 하고 있는지 알고 있어야 한다.
  2. 쓰레기 줍기 리팩토링(Litter-Pickup Refactoring): 이상하거나 더러운(yuck) 코드를 발견했을 때 고친다. 이를 지속하면 전반적으로 코드가 깨끗해진다.
  3. 이해하기 위한 리팩토링(Comprehension Refactoring): 코드를 보고 이해가 안 될 때, 이해한 뒤 이해에 맞게 코드를 수정한다. 내 머릿속에서만 코드를 이해하는 것이 아니라 팀원들도 이해할 수 있도록 수정하는 리팩토링이다.
  4. 준비로서의 리팩토링(Preparatory Refactoring): 새로운 기능을 추가하려고 할 때 기존의 코드가 새 기능과 맞지 않는다면 우선 기존의 코드를 정리하고 새 기능을 추가한다.
  5. 계획된 리팩토링(Planned Refactoring): 프로젝트 중간에 리팩토링을 끼워넣는 것. 많은 코드를 작성할 때 사용되곤 한다. 리팩토링을 잘 하는 팀은 작업을 훨씬 잘게 나눠 지속적으로 리팩토링하므로 이렇게 할 필요가 없다. 이 방식은 피하는 것이 좋다. 이 방식이 좋은 유일한 이유는 안 하는 것보다는 낫기 때문이다.
  6. 장기적인 리팩토링(Long Term Refactoring): 리팩토링에 시간이 많이 들어갈 때가 있다. 예컨대 복잡한 의존성이 있는 거대한 코드가 그런 경우다. 이럴 땐 장기적인 리팩토링을 수행한다. 코드 수정의 명확한 비전/목표를 정한다. 목표를 공유한 뒤 연관된 작업을 하면서 조금씩 수정한다. 목표를 향해 점진적으로 나간다는 느낌을 공유해야 한다.

언제 리팩토링을 할 것인가?

내가 지금 하는 일에 영향을 받지 않고 쉽고 빠르게 고칠 수 있는가? 그러면 즉각 실행한다. 이 때도 우선 테스트를 모두 성공하게 한 뒤 리팩토링을 시작한다(아직 코드를 작성하지 않아 실패하는 테스트는 비활성화할 수도 있다). 빨리 할 수 없다면 적어 둔다.

언제 리팩토링할지 정할 때 가장 중요한 것은 리팩토링의 범위를 정하는 것이다. 가능한 작은 단위로 쪼개서 수행한다.

리팩토링은 시간을 뺏는가?

아니다. 리팩토링을 하면 새 기능을 추가할 때 신속하게 할 수 있다.

리팩토링을 해야 하는 이유는 무엇인가?

리팩토링은 돌아가는 코드를 기능 추가 없이 고치는 것이므로 똑같은 일을 한 번 더 하는 것인가? 아니다. 설계에 신경쓰지 않으면 갈수록 코드 작성 속도가 떨어진다. 리팩토링은 좋은 설계에 기여한다. 리팩토링을 하면 더 많은 기능을 더 빠르게 적용할 수 있다.