코드 정리 관리
- 3.1 정리와 동작 변경 구분
- 3.2 연쇄적 정리
- 3.3 일괄 처리량
- 3.4 리듬
- 3.5 얽힘 풀기
- 3.6 정리 시점
어떻게 정리하는지는 배웠어. 이제 문제는 "언제, 얼마나" 정리하느냐야. 코드 정리를 잘하는 것과 코드 정리를 잘 관리하는 건 다른 이야기거든.
가장 중요한 원칙부터. 코드 정리와 동작 변경을 같은 커밋에 섞지 마. 하나의 PR에 리팩터링과 기능 추가가 섞여 있으면, 리뷰하는 사람이 "이건 정리한 거야, 동작을 바꾼 거야?" 구분할 수가 없어. 뭔가 터졌을 때 원인 찾기도 어렵고. 켄트 벡은 코드 정리를 별도의 커밋, 가능하면 별도의 PR로 분리할 것을 권해. 리뷰어가 "이건 정리만 한 거구나" 하고 빠르게 확인할 수 있고, 문제가 생기면 정리 커밋만 되돌릴 수 있고, 정리와 동작 변경의 역사가 명확하게 남으니까.
그런데 실제로 정리를 시작하면 연쇄적인 정리가 일어나. 보호 구문을 적용하다 보면 설명하는 변수가 필요해지고, 설명하는 변수를 만들다 보면 도우미를 추출하고 싶어지고, 도우미를 추출하다 보면 읽는 순서를 바꾸고 싶어지지. 하나를 정리하면 다른 정리 기회가 보이는 건 자연스러운 현상이야. 문제는 이 연쇄가 끝나지 않을 수 있다는 거야. 정신 차려보면 원래 하려던 기능 변경은 안 하고 정리만 몇 시간째 하고 있거든. 연쇄적인 정리는 하되, 멈출 줄 알아야 해. 지금 하려는 동작 변경에 도움이 되는 정리만 하고, 나머지는 나중을 위해 남겨둬. 정리는 끝이 없어.
일괄 처리량 문제도 있어. 정리를 모아서 한꺼번에 하면 효율적일 것 같지만, 배치가 커지면 리뷰가 어려워지고, 충돌 가능성이 높아지고, 되돌리기가 어려워져. 많은 파일을 건드릴수록 다른 사람의 변경과 부딪힐 확률이 올라가잖아. 반대로 너무 작게 쪼개면 커밋이 너무 많아져서 히스토리가 지저분해지고. 경험적으로 한 가지 종류의 정리를 한 번에 하는 게 좋은 기준이야. 보호 구문 적용만, 변수 이름 변경만, 함수 추출만 -- 이런 식으로.
코드 정리의 리듬도 중요해. "이번 스프린트에서 리팩터링 주간을 갖겠습니다" 같은 게 아니라, 매일의 작업 흐름 속에 자연스럽게 녹아 있어야 해. 켄트 벡이 제안하는 리듬은 이래: "정리, 정리, 정리, 동작 변경. 정리, 정리, 동작 변경." 기능을 구현하기 전에 짧은 정리를 몇 번 하고, 그다음 기능을 구현하는 거야. 분 단위로 정리하고, 분 단위로 동작을 변경해. 몇 시간씩 정리하는 게 아니라 몇 분 정리하고 몇 분 기능 구현하는 짧은 사이클. 이렇게 하면 정리를 위한 별도 시간을 확보할 필요가 없어.
현실에서는 얽힘이 생기기 마련이야. 기능을 구현하다가 정리가 필요한 부분을 발견하고, 정리하다 보니 동작 변경도 같이 해버리고. 정신 차려보면 작업 디렉터리에 정리와 기능 변경이 뒤죽박죽 섞여 있지. 이럴 때는 변경 사항을 다 넣어두고 정리만 골라서 별도 커밋으로 분리하거나, 더 과감하게 변경 사항을 전부 버리고 처음부터 다시 하되 이번에는 정리를 먼저 해. 두 번째에는 훨씬 빨라. 이미 뭘 해야 하는지 알고 있으니까.
마지막으로 코드 정리 시점. 켄트 벡은 네 가지를 제시해:
먼저(First) -- 동작 변경 전에 정리해. 정리를 하면 동작 변경이 더 쉬워질 때. 이게 "Tidy First?"라는 책 제목의 의미야.
이후에(After) -- 동작 변경 후에 정리해. 기능 구현을 마치고 나니 방금 작업한 코드를 더 깔끔하게 만들 수 있겠다 싶을 때.
나중에(Later) -- 지금은 안 하고 할 일 목록에 적어둬. 지금 당장 정리의 이점이 크지 않을 때.
안 한다(Never) -- 코드가 다시 읽힐 일이 없거나, 곧 교체될 예정이거나, 정리해도 동작 변경이 쉬워지지 않을 때.
대부분의 경우 "먼저"가 가장 효과적이야. 동작 변경에 필요한 만큼만 정리하고, 바로 동작을 변경하면 정리의 가치가 즉시 실현되거든.
정리
3장 읽고 기억할 거 세 가지:
- 정리와 동작 변경을 같은 커밋에 섞지 마. 분리해야 리뷰도 쉽고 되돌리기도 쉬워
- 정리는 분 단위로 작게, 자주, 일상적으로 해. 연쇄적 정리에 빠져서 몇 시간씩 쓰지 말고, 한 가지 종류씩 끊어
- 정리 시점은 네 가지인데, "먼저(Tidy First?)"가 대부분 정답이야. 동작 변경에 필요한 만큼만 정리하고 바로 변경해