리팩터링의 첫 단계는 항상 똑같다. 리팩터링할 코드 영역을 꼼꼼하게 검사해줄 테스트 코드들 부터 마련해야 한다. 프로그램이 클수록 수정 과정에서 예상치 못한 문제가 발새할 가능성이 크다. '디지털 시대의 연약한 자여, 그대 이름은 소프트웨어'
여기서 잠시 멈추가 방금 한 일에 대해 생각해보자. 무엇보다도 반복문을 쪼개서 성능이 느려지지 않을까 걱정할 수 있다. 이처럼 반복문이 중복되는 것을 꺼리는 이들이 많지만, 이 정도 중복은 성능에 미치는 영향이 미미할 때가 많다. 실제로 이번 리팩터링 전과 후의 실행시간을 측정해보면 차이를 거의 느끼지 못할 것이다. 경험 많은 프로그래머조차 코드의 실제 성능을 정확히 예측하지 못한다. 똑똑함 컴파일러들은 최신 캐싱 기법등으로 무장하고 있어서 우리의 직관을 초월하는 결과를 내어주기 때문이다. 또한 소프트웨어 성능은 대체로 코드의 몇몇 작은 부분에 의해 결정되므로 그 외의 부분은 수정한다고 해도 성능 차이를 체감할 수 없다.
그러나 때로는 리팩터링이 성능에 상당한 영향을 주기도 한다. 그런 경우라도 나는 개의치 않고 리팩터링한다. 잘 다듬어진 코드라야 성능개선 작업도 훨씬 수월하기 때문이다.
따라서 리팩터링으로 인한 성능 문제에 대한 내 조언은 '특별한 경우가 아니라면 일단 무시하라'는 것이다. 리팩터링 때문에 성능이 떨어진다면, 하던 리팩터링을 마무리하고 나서 성능을 개선하자.
처음보다 코드량이 부쩍 늘었다. 그 외에 달라진 점이 없다면 안 좋은 징조지만, 다행히 그렇지는 않다. 추가된 코드 덕분에 전체 로직을 구성하는 요소 각각이 더 뚜렷이 부각되고, 계산하는 부분과 출력 형식을 다루는 부분이 분리됐다. 간결함이 지혜의 정수일지 몰라도, 프로그래밍에서 만큼은 명료함이 진화할 수 있는 소프트웨어의 정수다.
리팩터링은 대부분 코드가 하는 일을 파악하는 데서 시작한다. 그래서 코드를 읽고, 개선점을 찾고, 리팩터링 작업을 통해 개선점을 코드에 반영하는 식으로 진행한다. 그 결과 코드가 명확해지고 이해하기 더 쉬워진다. 그러면 또 다른 개선점이 떠오르며 선순환이 형성된다.
좋은 코드를 가늠하는 확실한 방법은 '얼마나 수정하기 쉬운가'다.