이 책의 1장은 기법을 가르치지 않는다. 대신 하나의 태도를 세운다 — 코드는 돌아가기만 해서는 부족하고, 오래 살아남으며 여러 사람이 함께 다룰 수 있어야 한다는 것. 이 장은 뒤따르는 모든 기법의 이유를 먼저 심어 두는 서문에 가깝다.
깨끗한 코드는 속도를 늦추지 않는다
가장 먼저 남는 문장은 “빨리 가는 유일한 방법은 코드를 깨끗하게 유지하는 것”이라는 말이다. 처음에는 품질과 속도가 서로 반대처럼 느껴진다. 급한 일정에서는 일단 돌아가게 만들고 나중에 정리하고 싶어진다. 하지만 그 “나중”이 쌓이면 작은 수정도 오래 걸리고, 코드를 읽는 시간보다 추측하는 시간이 길어진다.
책은 이 현상을 “나쁜 코드가 쌓는 대가”로 설명한다. 지저분한 코드에 기능을 하나 더 얹을 때마다 생산성은 조금씩 깎이고, 어느 순간 팀은 방향을 잃는다. 새 기능 하나를 넣으려 해도 여기저기 얽힌 코드가 함께 깨지고, 그 여파를 추적하느라 시간이 녹는다. 그래서 생산성 곡선은 시간이 갈수록 0에 수렴한다.
flowchart LR A["일단 돌아가게<br/>(정리는 나중에)"] --> B[나쁜 코드 축적] B --> C["수정마다 추측·회귀"] C --> D["생산성 → 0 수렴"] A2["건드린 곳을 조금씩 정리"] --> B2[부채 증가 완만] B2 --> C2["변경 영향 예측 가능"] C2 --> D2["지속 가능한 속도"]
깨끗한 코드는 멋진 구조를 과시하는 코드가 아니라, 다음 사람이 의도를 빠르게 파악하고 안전하게 고칠 수 있는 코드에 가깝다. 코드는 한 번 작성되고 끝나는 문서가 아니라 계속 읽히고 바뀌는 대상이기 때문이다. 실제로 코드를 짜는 시간과 읽는 시간의 비율은 10 대 1을 훌쩍 넘는다. 읽기 좋게 만드는 데 든 노력은 그 열 배로 되돌아온다.
단순한 규칙에서 시작하기
책에서는 켄트 벡의 네 가지 규칙(단순한 설계)을 소개한다. 우선순위 순으로, 모든 테스트를 통과하고, 중복을 없애고, 프로그래머의 의도를 드러내고, 클래스와 메서드 수를 줄이라는 내용이다. 이 규칙들은 거창한 설계 원칙이라기보다 매일 코드를 만질 때 확인할 수 있는 기준에 가깝다.
테스트가 통과해야 변경을 믿을 수 있고, 중복이 줄어야 수정 지점이 명확해진다. 이름과 구조가 의도를 드러내면 설명을 덧붙이지 않아도 코드가 읽힌다. 그리고 불필요한 구성 요소를 줄이면 코드베이스 전체가 가벼워진다. 네 가지는 따로 떨어진 규칙이 아니라 서로 연결되어 있다.
판단 기준: 규칙의 순서 자체가 판단 기준이다. 중복 제거와 의도 표현이 충돌하면 앞에 놓인 것을 먼저 챙긴다. 하지만 어느 것도 “모든 테스트 통과”를 앞서지는 못한다 — 동작을 깨면서 얻는 깔끔함은 깔끔함이 아니다.
표현이 곧 정리다
같은 동작이라도 이름과 구조가 의도를 드러내는가에 따라 읽는 비용이 갈린다. 다음 두 조각은 결과가 같지만, 읽는 사람이 감당해야 하는 해석의 양이 다르다.
// before — 무엇을 거르는지 코드를 해독해야 안다
public List<int[]> getThem() {
List<int[]> list1 = new ArrayList<>();
for (int[] x : theList)
if (x[0] == 4) list1.add(x);
return list1;
}// after — 이름이 의도를 대신 말한다
public List<Cell> getFlaggedCells() {
List<Cell> flaggedCells = new ArrayList<>();
for (Cell cell : gameBoard)
if (cell.isFlagged()) flaggedCells.add(cell);
return flaggedCells;
}두 조각의 제어 흐름은 완전히 같다. 바뀐 것은 이름과 타입뿐인데, 뒤쪽은 주석 한 줄 없이도 “표시된 칸을 모은다”가 읽힌다. 이것이 1장이 말하는 정리의 본질이다 — 구조를 뒤엎지 않고도, 이름을 정확히 붙이는 것만으로 코드가 스스로 설명하게 만든다. 이 감각은 2장(이름)과 3장(함수)에서 구체적인 기법으로 이어진다.
우리는 저자다
책은 프로그래머를 “저자”라고 부른다. 저자에게는 독자가 있고, 좋은 저자는 독자를 배려한다. 그런데 코드의 첫 번째 독자는 컴파일러가 아니라 사람이다 — 다음 기능을 얹으러 이 파일을 여는 동료, 그리고 몇 달 뒤의 나. 코드를 짜는 시간과 읽는 시간의 비율은 10 대 1을 넘고, 새 코드를 쓰는 일조차 주변의 옛 코드를 읽는 것에서 시작한다. 그러니 읽기 쉽게 만드는 것은 배려가 아니라 생산성의 문제다.
여기서 나오는 것이 “이중성”이다. 코드는 지금 당장 요구를 처리해야 하고(현재), 동시에 앞으로도 쉽게 바뀔 수 있어야 한다(미래). 급할수록 현재만 챙기고 싶지만, 이 책 전체가 붙드는 관점은 미래의 변경 가능성을 지금 포기하지 말라는 것이다. 미래를 위한 배려가 곧 나의 다음 속도를 지킨다.
판단 기준: 어떤 코드가 “깨끗한가”를 스스로 물을 때, “지금 돌아가는가”만이 아니라 “다음 사람이 5분 안에 안전하게 고칠 수 있는가”를 함께 묻는다. 뒤 질문에 자신이 없다면 아직 정리가 남은 것이다.
보이스카우트 규칙
클린 코드는 한 번에 완성되는 상태가 아니다. 이미 존재하는 코드 전체를 새로 쓰는 일보다, 내가 건드린 주변을 조금 더 낫게 남기는 일이 현실적이다. “캠핑장은 처음 왔을 때보다 깨끗하게 하고 떠나라”는 보이스카우트 규칙이 그 감각이다. 변수 이름 하나를 더 분명하게 바꾸거나, 중복된 조건을 함수로 빼거나, 읽기 어려운 흐름을 나누는 정도여도 충분하다.
중요한 점은 정리를 별도의 이벤트로 미루지 않는 것이다. 기능을 추가하는 동안 작은 청소를 계속하면 코드가 급격히 망가지는 속도를 늦출 수 있다. 반대로 작은 어지러움을 계속 방치하면 어느 순간부터는 아무도 쉽게 손대지 못하는 코드가 된다.
함정: 보이스카우트 규칙을 “지나가는 김에 대대적으로 리팩터링” 으로 오해하면 오히려 변경이 커져 리뷰와 회귀 위험이 늘어난다. 규칙의 핵심은 크기가 아니라 방향이다 — 매 커밋이 코드를 아주 조금씩 더 나은 쪽으로 옮긴다. 큰 개선이 필요하면 별도 작업으로 떼어낸다.
정답보다 태도에 가깝다
클린 코드에는 왕도가 없다. 언어, 팀, 도메인에 따라 좋은 코드의 모양은 조금씩 달라진다. 다만 공통적으로 남는 태도는 있다. 코드를 읽는 사람을 배려하고, 변경을 두려워하지 않도록 만들고, 발견한 문제를 가능한 작은 단위로 고쳐 나가는 것이다.
그래서 이 장은 특정 기법보다 기준을 세우는 장에 가깝다. 나쁜 코드를 만드는 것은 시간이 없어서가 아니라, “나중에 정리하겠다”는 미룸이 반복되기 때문이다. 그리고 르블랑의 법칙대로 나중은 결코 오지 않는다. 그러니 지금, 건드린 자리에서, 조금.
정리
- 빨리 가는 유일한 방법은 코드를 깨끗하게 유지하는 것이다. 나쁜 코드는 매 변경마다 이자를 물리고, 생산성 곡선을 0으로 끌어내린다.
- 켄트 벡의 네 규칙은 우선순위가 있다: 테스트 통과 → 중복 제거 → 의도 표현 → 요소 최소화. 순서가 곧 판단 기준이다.
- 정리는 구조를 뒤엎는 일이 아니다. 이름 하나를 정확히 붙이는 것만으로도 코드는 스스로 설명하기 시작한다.
- 보이스카우트 규칙은 크기가 아니라 방향이다. 매 커밋이 코드를 아주 조금 더 낫게 남긴다.
- 클린 코드는 정답이 아니라 태도다. “나중에”를 “지금 조금”으로 바꾸는 습관이 전부다.
다음장으로 2장