리팩터링 2판 - YES24
개발자가 선택한 프로그램 가치를 높이는 최고의 코드 관리 기술마틴 파울러의 『리팩터링』이 새롭게 돌아왔다.지난 20년간 전 세계 프로그래머에게 리팩터링의 교본이었던 『리팩토링』은,
www.yes24.com
오늘 리뷰할 책은 [리팩터링 2판] (부제: 코드 구조를 체계적으로 개선하여 효율적인 리팩터링 구현하기)라는 책이다. 사실 클린 코드에 관한 다른 책을 먼저 보려고 했는데, 클린 코드보다 리팩터링에 대한 내용이 더 흥미가 있어서 이 책을 먼저 보게 되었다.
책은 자바스크립트를 이용해 예제를 보여주며 다양한 상황에서의 적용 가능한 기법들을 말해준다. 자바도 잘 모르고 자바스크립트는 아예 몰랐지만 책 초반에 나온 예제를 보면서 볼만하다고 생각해서 부담 없이 읽을 수 있었다. 사용하는 언어가 다르긴 하더라도 개념 자체는 이해할 수 있었고 어려운 문법이 나오지는 않았기 때문이다.
이는 리팩터링과 동시에 클린 코드 영역도 다루기 때문이라고 생각이 든다. 실제로 책에서 리팩터링 예제를 보여주면서 자신이 생각하기에 지저분한 코드라 생각해서 인라인 시키는 등의 내용이 있었다. 또, 아래에 정리한 내용에 있지만 리팩터링이라는 것 자체가 추후에 개선하기 쉽게 만들기 위함이기 때문에 더욱 읽기 쉬운 코드를 지향했다고 생각한다.
그렇다고 책 자체가 재밌지는 않았다. 생각보다 읽는데 너무 오래 걸렸다. 550쪽 정도 분량인데 2~3주 생각했던 것과 달리 4주 넘게 읽었다. 물론 코드도 있고 동작과 구성을 생각하면서 읽기 때문이기도 한데 읽기 귀찮았다.
재미는 없었지만 도움은 많이 됐다. 책을 읽다보니 회사에서 얼마 전에 개발한 모듈의 코드에서도 너무 거슬리는 부분들을 스스로 느낄 수 있었다. 신규 개발했음에도 여기저기 중복 코드가 있고, 함수 하나가 길어지기도 하고, 함수명이 맞지 않는 것도 같은 약간의 악취가 나고 있었다. 그리고 책의 조언대로 차례대로 조금씩 수정 중에 있다.
요새 이런 책들을 보니까 회사에 단위 테스트 사용 문화가 없는 것이 너무 아쉽다. 나 혼자라도 하고 싶은데 핑계이긴 하겠지만 단위 테스트에 아는 게 없다 보니까 시도하고 적용하기 어렵다. 배울 사람이 필요하다고 느꼈고, 나라도 그런 사람이 되어야 한다는 것을 알지만, 막상 시도하기에는 쉽지 않다.
조만간 BOB 멘토님 만나뵈면, 리팩터링 시 단위 테스트 관련해서 여쭤볼 예정이다.
참고로, 책에서는 자바스크립트 언어를 사용하기 때문에 mocha라는 테스트 프레임 워크를 사용했다고 했다. 책에 테스트 코드는 별도로 없지만.
아무튼 여기까지가 느낀점이고 아래부터는 간단히 정리한 내용이다. 예제 같은 것들은 찾아보니 다른 블로그에서도 이 책을 요약해놔서 쉽게 찾을 수 있다. 그래서 '리팩터링' 자체에 대한 개념? 같은 것만 정리하고자 한다.
아무튼 정리
리팩터링은 필요하다 싶을 때, 또는 기능을 추가할 때, 언제든지 필요성이 있다고 생각되면 그 즉시 진행해야 한다. 이는 코드에서 악취가 나는 시점이라고 할 수도 있다. 그럼 악취는 언제 나는가? 이건 숙련된 사람의 직관만큼 정확한 기준은 없다. 해야 할 필요가 있는 코드들을 보고 어디를 리팩터링 하면 좋을지는 오랜 경험이 중요하다. 책의 예제와 설명을 보면서 충분히 이해가 가능했다. 책의 예제는 간단한 코드들이라 그렇게 악취가 많이 나지는 않겠지만, 충분히 이 예제들을 내가 작성하는 코드들에 대입해서 볼 수 있다.
기능을 추가하는 중이었다면 기능을 추가하는 것만 생각해야 한다. 반대로 리팩터링을 하고 있다면, 기능을 추가하지 말고 리팩터링만 생각해야 한다. 둘을 같이 진행하지 말아야 한다.
리팩터링 시에는 기존의 코드와 버그도 동일해야 한다. 여기서 버그는 알려진 버그 기준이며, 리팩터링 중에 발견된 기능은 간단하다면 수정을 진행해도 된다.
모든 리팩터링은 리팩터링 전 테스트 코드 작성이 필수적이다. 그리고 리팩터링 단계를 최대한 작게 나눠서 '빌드 - 테스트 - 커밋'을 반복해야 한다. 책에서 소개되는 가장 작은 단위는 문장 슬라이스(변수 선언 위치를 바꾸기 등)와 함수명 변경 등이 있다. 이때도 조금만 바뀌더라도 '빌드 - 테스트 - 커밋'을 수행해야 한다.
리팩터링은 추후 유지보수나 기능 추가 시 코드 분석이 쉬워지게 하는 목적이다. 즉, 비용성 측면에서 효율적으로 하는 것이며, 단순한 클린 코드처럼 이쁘게만 작성하는 것과는 다르다.
마찬가지로, 유지보수나 기능 추가 시 코드 분석이 쉬워지게 하는 목적이다보니, 리팩터링으로 인해 실행 성능은 조금 혹은 많이 떨어질 수도 있다. 그렇다 할지라도 우선 리팩터링을 마쳐야 한다. 떨어진 성능은 리팩터링이 끝나고 고민해도 되며, 리팩터링 후에 이미 코드가 분석하기 쉬워진다면 성능이 떨어진 곳을 찾기 쉬워지며 향상하는 것도 어렵지 않다.
리팩터링으로 성능이 떨어진 곳을 찾기 위해서는 프로파일러를 이용하면 된다. 프로파일러는 프로그램을 분석해 시간/공간을 많이 잡는 지점을 확인할 수 있게 해준다.
성능 개선과 관련해서 한 가지 사실은 코드 전반적으로 성능 개선은 쓸모가 없다는 것이다. 전체 코드 중 극히 일부에서 전체 시간의 대부분을 소비하기 때문에, 그 부분만 성능 개선을 하면 된다. 따라서, 전반적인 코드 성능 개선을 한다는 것은 개선 과정의 90%는 사실상 낭비로 볼 수 있다.
흔히 말하기를 두 번 이상 반복되면 함수로 추출하라고 한다. 하지만, 저자는 자신의 경험상 코드의 목적성을 한 번에 파악할 수 없다면 추출한다고 말한다. 6줄 이상이면 보통 냄새를 풍기기 시작하는데, 실제로 한 줄짜리 함수라도 추출할 필요가 있을 수도 있다는 것이다.
이러한 예로, 켄트 백의 스몰토크 시스템에서 흑백 화면에서 강조를 위한 highlight() 메서드를 사용하고 있었는데, 이 메서드는 단순히 reverse() API만 호출하고 있었다는 것이다. 즉, reverse() API의 이름은 한 번에 그 목적을 알기 어려우니 함수명만 변경해서 사용하는 Wrapping 한 개념이다.
예전에는 함수를 많이 만들면 만들수록 스택을 많이 타고 들어가면서 성능에 문제가 있다고 했다. 하지만, 요즘은 오히려 함수가 짧아지면 캐싱이 쉬워 컴파일러 최적화가 잘 된다. 그러니 걱정 말고 함수를 추출하면 된다.
그리고, 보통은 하나의 반복문에서 a작업과 b작업을 하고 있는 것을 두 개의 반복문으로 나누기를 꺼려한다. 다시 말하지만, 리팩터링과 최적화는 다르기 때문에 a작업과 b작업을 분리하는 리팩터링을 먼저 하자. 그러고 나서 최적화를 시키는 편이 더 이롭다. 다시 합쳐도 되고, a작업과 b작업의 위치를 다른 곳으로 이동시킬 수도 있고, 더 좋은 성능 최적화 방법이 있을 수도 있다. 그러니 악취가 난다면 먼저 리팩터링부터 해보자.
C++ 메서드를 안전하게 추출하는 방법은 '제이 바주자'의 글에서 검증된 몇 가지 리팩터링 기법만을 조합해 사용한 예제가 있다.
Safely extract a function in any C++ code – Jay Bazuzi – Author of Unremarkable Code
Safely extract a function in any C++ code
Given arbitrarily-complex C++ code with incomplete test coverage (aka The Real World) how can you extract a function, without relying on complete understanding or complete test coverage to ensure correctness of the refactoring?
jay.bazuzi.com
다른 책 추천으로는 '레거시 코드 활용 전략', '리팩터링 워크북'이 있다.
책정보, 레거시 코드 활용 전략 : 네이버 책 (naver.com)
레거시 코드 활용 전략
▶ 레거시 코드 활용 전략에 관한 내용을 담은 전문서적입니다.
book.naver.com
책정보, 리팩터링 워크북 : 네이버 책 (naver.com)
리팩터링 워크북
개발자를 위한 워크북. 이 책은 프로그램의 설계와 구현을 위한 리팩터링 기법에 관하여 다루고 있는 것으로 예제를 통해 종합적인 리팩터링 연습을 할 수 있도록 구성했다.《리팩터링 워크북
book.naver.com
'리뷰 > 책 리뷰' 카테고리의 다른 글
[IT/리뷰] 글로벌 소프트웨어를 꿈꾸다 (0) | 2022.09.04 |
---|---|
[IT/리뷰] Clean Code (0) | 2022.08.21 |
[IT/리뷰] 실용주의 소프트웨어 개발 리뷰 (0) | 2022.05.08 |
[IT/리뷰] Effective C++ (3판) (0) | 2022.03.29 |
[IT/리뷰] 거꾸로 배우는 소프트웨어 개발 리뷰 (0) | 2022.03.04 |