이런 상황이라면
3개월 전 자기가 짠 코드를 열었다가 한참을 들여다본 적 있는 사람에게 맞는다. 팀에 코드 리뷰 기준이 없어서 "이게 좋은 코드인가"를 매번 말싸움으로 정하는 상황에도 좋다. 반대로 시스템 경계나 배포 구조를 고민하는 단계라면 이 책보다 아키텍처 서적이 낫다.
한눈에 보기
이 책은 "돌아가는 코드"와 "살아남는 코드"는 다르다는 문제를 다룬다. 대부분의 개발 비용은 새로 짜는 데가 아니라 남의 코드를 해독하는 데서 발생한다. 마틴은 이 해독 비용을 줄이는 구체적 규칙을 나열한다. 이름 짓기, 함수 크기, 주석의 역할, 클래스 책임, 오류 처리, 테스트까지 층층이 내려간다. 각 장은 나쁜 코드를 먼저 보여주고 단계별로 고쳐 나가는 방식이다. 그래서 이 책은 원칙집이라기보다 리팩터링 실습 기록에 가깝다.
기존의 코딩 책이 "어떻게 동작하게 만드는가"를 가르쳤다면, 이 책은 "어떻게 읽히게 만드는가"를 가르친다. 성능이나 아키텍처가 아니라 가독성을 1급 요구사항으로 올려놓는다는 점이 다르다. 또 하나, 깨끗함을 취향이 아니라 규율의 문제로 본다. 마감이 급해서 대충 짜는 선택은 빠른 게 아니라 이자를 붙여 빌리는 것이라고 말한다. 그래서 이 책의 결론은 기술이 아니라 태도로 수렴한다.
핵심 인사이트
- 01
주석은 실패의 흔적이다
좋은 주석은 코드가 설명하지 못한 것을 채우는 게 아니라, 애초에 필요 없어야 한다. 주석은 코드와 달리 컴파일되지 않기 때문에 아무도 틀렸다고 알려주지 않는다. 로직은 세 번 수정되는 동안 위의 설명은 처음 그대로 남는다. 그 순간 주석은 도움이 아니라 거짓말이 된다. 흔한 예가 "// 사용자 검증" 위에 붙은 열 줄짜리 블록이다. 그 블록을 validateUser()라는 함수로 뽑아내면 주석은 저절로 사라진다. 그래서 주석을 쓰고 싶어질 때가, 사실은 코드를 고칠 신호다.
- 02
이름 짓는 시간은 낭비가 아니다
변수 이름은 문서의 최소 단위다. 사람이 코드를 읽을 때 뇌는 구조보다 단어를 먼저 처리한다. 이름이 모호하면 독자는 정의부로 점프해서 실제 동작을 확인해야 하고, 그 왕복이 이해 비용의 대부분을 차지한다. d, tmp, data, list 같은 이름은 타이핑을 3초 아끼고 독자에게 30초를 물린다. 반대로 elapsedTimeInDays처럼 길어도 의도가 드러나면 점프가 사라진다. 이름을 고민하는 5분은 미래의 읽기 시간을 수십 번 줄이는 투자다.
- 03
함수는 한 가지만, 그리고 작게
함수가 커지는 이유는 대개 추상화 수준이 섞이기 때문이다. HTTP 응답을 파싱하는 줄과 세금을 계산하는 줄이 한 함수에 있으면, 읽는 사람은 매 줄마다 사고의 고도를 바꿔야 한다. 마틴은 함수가 한 가지 일만 하는지 판단하는 기준으로 "의미 있는 이름으로 더 쪼갤 수 있는가"를 제시한다. 더 쪼갤 수 있다면 아직 여러 일을 하는 중이다. 실무에서 흔한 반례는 "함수가 너무 많아지면 오히려 헷갈린다"는 반발인데, 대개 이름이 나쁠 때 생기는 문제다. 잘 이름 붙은 작은 함수들은 목차처럼 읽힌다.
- 04
보이스카우트 규칙: 리팩터링은 프로젝트가 아니다
코드 정리를 별도 일정으로 잡으면 그 일정은 영원히 밀린다. 우선순위 회의에서 "고객에게 보이지 않는 작업"은 언제나 뒤로 간다. 그래서 마틴은 캠프장 규칙을 가져온다. 들어왔을 때보다 조금 더 깨끗하게 두고 나가라는 것이다. 오늘 버그를 고치러 연 파일에서 변수 하나를 제대로 된 이름으로 바꾸는 정도면 충분하다. 이 방식은 승인을 받을 필요도, 별도 브랜치도 필요 없다. 큰 정리를 한 번 하는 것보다, 매번 손댈 때마다 1%씩 좋아지는 쪽이 실제로는 훨씬 멀리 간다.
- 05
깨끗한 코드의 전제는 테스트다
리팩터링이 무서운 진짜 이유는 실력이 아니라 확신의 부재다. 고쳤을 때 뭐가 깨지는지 알 수 없으면, 아무도 남의 코드를 건드리지 않는다. 그 결과 코드는 손대기 싫은 상태로 굳고, 새 기능은 옆에 덧붙이는 방식으로만 들어온다. 테스트는 이 잠금을 푸는 열쇠다. 그래서 이 책은 테스트 코드도 제품 코드와 같은 기준으로 관리하라고 요구한다. 지저분한 테스트는 유지되지 않고, 유지되지 않는 테스트는 곧 삭제되며, 삭제된 순간 코드는 다시 얼어붙는다.
이렇게 적용한다
상황리뷰에서 "이 코드 좀 지저분한데요"라는 말이 나왔지만 뭐가 문제인지 서로 설명하지 못할 때
감상 대신 체크 항목으로 바꿔 말한다. 함수 길이, 이름의 구체성, 중복 여부, 인자 개수 네 가지만 먼저 팀 기준으로 못 박는다. 취향 논쟁이 아니라 합의된 규칙 위반으로 지적하면 대화가 짧아지고 감정도 덜 상한다.
상황레거시 파일을 열었는데 300줄짜리 함수 하나가 전부일 때
전체를 다시 짜려 하지 말고 그 함수 안에서 주석이 붙어 있는 구간만 찾는다. 주석 한 줄이 곧 함수 하나의 이름이다. 그 구간을 그대로 함수로 추출하고 주석을 지운다. 동작은 바꾸지 않으므로 위험이 낮고, 함수 하나가 목차 수준으로 줄어든다.
상황일정이 급해서 일단 돌아가게만 짜고 넘어가려는 순간
"나중에 정리하겠다"는 결심 대신 그 자리에 흔적을 남긴다. TODO가 아니라 이슈 티켓으로 만들고 어떤 조건에서 무엇을 바꿀지 한 줄로 적는다. 기록되지 않은 부채는 갚을 대상이 아니라 그냥 사라진 약속이 된다.
ACTION ITEMS
오늘 바로 할 수 있는 것.
- ✓오늘 작업한 파일에서 의미 없는 이름 세 개를 골라 의도가 드러나는 이름으로 바꾼다.
- ✓가장 긴 함수 하나를 열어 주석이 붙은 구간을 함수로 추출하고 그 주석을 지운다.
- ✓인자가 세 개 이상인 함수를 하나 찾아 객체로 묶거나 함수를 분리한다.
- ✓팀 채널에 코드 리뷰 기준 네 줄을 올려 합의 여부를 물어본다.
- ✓테스트가 없는 함수 하나를 골라 가장 기본적인 케이스 하나만 테스트로 남긴다.
밑줄 그은 문장
“'나중에'는 오지 않는다. 나쁜 코드의 이자는 매일 붙는다.”
이 책이 답하지 않는 것
예제가 자바 중심이라 함수형 언어나 동적 타입 환경에서는 그대로 옮기기 어려운 조언이 섞여 있다. 또한 함수를 잘게 쪼개라는 원칙은 과하게 적용하면 오히려 추적이 어려워진다는 반론도 오래전부터 있었다. 시스템 경계 설계나 팀 협업 프로세스는 이 책의 범위 밖이다.
이 통찰의 근거가 궁금하다면?
원서·번역서 정보와 가격은 판매처에서 확인하세요.
※ 구매 링크는 제휴 활동의 일환이며, 이를 통해 일정액의 수수료를 제공받습니다. 구매자에게 추가 비용은 발생하지 않습니다.
비슷한 주제의 책
NEWSLETTER
매일 아침, 새로운 인사이트
하루의 시작을 도와줄 책 한 권의 핵심과 실천 과제를 보내드립니다.



