클린 코드 실전 강의 교재¶
4장 — 주석¶
대상: Java/Spring 백엔드 입문~중급 수강생 형식: 개념 → 비유 → Before/After → 함정 → 체크리스트 → 퀴즈 전제 환경: Java 17+, Spring Boot 3.x
0. 이 장을 시작하기 전에¶
0.1 학습 목표¶
- "주석은 나쁜 코드를 보완하지 못한다" — 책의 가장 격한 단언을 이해한다.
- 좋은 주석 8종 vs 나쁜 주석 16종 을 구분한다.
- 3장(함수)이 대부분의 주석을 불필요하게 만든다는 연결 관계를 본다.
0.2 큰 그림¶
[ 원칙 ] [ 좋은 주석 (8) ] [ 나쁜 주석 (16) ]
코드로 의도 표현 법적 주절거림
주석은 실패의 인정 정보 제공 중복
의도 설명 오해 여지
의미 명료화 의무적
결과 경고 이력
TODO 잡음
중요성 강조 함수·변수로 표현 가능
공개 API Javadoc 위치 표시·닫는 괄호
공로·저자·HTML
주석 처리된 코드
전역·과다 정보
모호한 관계·함수 헤더
비유 — 주석은 "사과문"입니다.
좋은 코드는 사과할 일이 없습니다. 주석을 달고 있다는 것은 코드가 자기 의도를 스스로 말하지 못하고 있다는 신호입니다. 그래서 4장은 사과문을 쓰지 말고 코드를 고치라고 말합니다.
0.3 현업에서 왜 중요한가¶
- 주석은 코드가 진화해도 같이 진화 안 함 → 시간이 지나면 거짓말이 됨.
- 위에서 본 "Q. 코드로 의도를 표현하라" 가 가장 강한 처방.
- Effective Java Item 56(공개 API Javadoc) 만 예외 — 그 외는 가능한 한 적게.
4.1 주석은 나쁜 코드를 보완하지 못한다¶
한 줄 정의¶
코드가 엉망이면 → 정리. 주석 추가가 답이 아님. "엉망인데 주석으로 설명" = "사과로 무마".
사례¶
// 이 줄은 정말 이상하지만 X 때문에 그렇게 둬야 함
String x = something.weird() + ".magic";
// → 함수 추출로 의도를 이름이 말하게
String x = buildMagicPath(something);
4.2 코드로 의도를 표현하라!¶
한 줄 정의¶
주석으로 설명할 만한 것은 함수·변수 이름 으로 옮길 수 있다.
Before / After¶
// Before — 주석으로 의도 설명
// 직원에게 복지 혜택을 받을 자격이 있는지 검사
if ((employee.flags & HOURLY_FLAG) && (employee.age > 65)) ...
// After — 함수 추출 + 이름이 말함
if (employee.isEligibleForFullBenefits()) ...
3장 함수 추출(6.1) 의 자연스러운 연장.
4.3 좋은 주석 — 8종¶
가능한 한 적게 — 그래도 정당한 경우.
(1) 법적인 주석¶
// Copyright (C) 2008 by ObjectMentor, Inc. All rights reserved.
// Released under the terms of the GNU General Public License version 2 or later.
회사·라이선스 표시. 필수.
(2) 정보를 제공하는 주석¶
// kk:mm:ss EEE, MMM dd, yyyy 형식
Pattern timeMatcher = Pattern.compile("\\d*:\\d*:\\d* \\w*, \\w* \\d*, \\d*");
정규식의 형식 의미 등 코드로 표현하기 어려운 정보.
단 — 더 좋은 해법: 그 의미를 변수 이름으로 옮기거나 enum/상수로 정리.
(3) 의도를 설명하는 주석¶
// 스레드를 대량 생성하는 방법으로 어떻게든 경쟁 조건을 만들어보려 한다.
for (int i = 0; i < 25_000; i++) {
new ThreadHelper(...).start();
}
왜 이렇게 코드를 짰는지 (의도) — 코드 자체는 표현 못 하는 영역.
(4) 의미를 명료하게 밝히는 주석¶
assertTrue(a.compareTo(a) == 0); // a == a
assertTrue(a.compareTo(b) != 0); // a != b
assertTrue(ab.compareTo(ab) == 0); // ab == ab
비교 결과의 의미 해설. 단 — 표준 라이브러리 호출이면 보통 불필요.
(5) 결과를 경고하는 주석¶
또는 @Disabled 같은 표준 메커니즘 우선.
(6) TODO 주석¶
// TODO-MdM 현재는 필요하지 않으나 모델 다운로드 후 변경 예정
protected VersionInfo makeVersion() throws Exception { return null; }
단 — IDE가 일괄 검색해서 정기적으로 해결할 것. 영구 TODO는 죽은 약속.
(7) 중요성을 강조하는 주석¶
생략하기 쉬운 코드의 결정적 중요성 명시.
(8) 공개 API Javadoc¶
/**
* 주문 합계를 계산한다.
*
* @param order null 불가
* @return 0 이상
* @throws IllegalArgumentException order가 null
*/
public Money totalAmount(Order order) { ... }
→ Effective Java Item 56 과 동일.
4.4 나쁜 주석 — 16종 카탈로그¶
(1) 주절거리는 주석¶
→ 누구에게 하는 말? 무슨 일이 일어났다는 건지? 불완전한 의도 → 코드를 고치든 명확히 다시 쓰든.
(2) 같은 이야기를 중복하는 주석¶
이름이 이미 말함 → 주석 중복.
(3) 오해할 여지가 있는 주석¶
i = 1 부터인지 i > 1 부터인지 모호. 틀린 정보를 줄 위험.
(4) 의무적으로 다는 주석¶
/**
* @param title CD 제목
* @param author 저자
* @param tracks 트랙 수
* @param durationInMinutes 길이 (분)
*/
public void addCD(String title, String author, int tracks, int durationInMinutes) { ... }
자명한 매개변수에 의무적 Javadoc — 정보 0, 노이즈만.
(5) 이력을 기록하는 주석¶
/*
* 변경 이력 (11-Oct-2001)
* ------------------------
* 11-Oct-2001: 클래스 재작성
* 05-Nov-2001: 새로운 메서드 추가
*/
→ Git 이 기억함. 코드에서 즉시 삭제.
(6) 있으나 마나 한 주석¶
→ 자명. 노이즈.
(7) 무서운 잡음¶
위 6번의 연속 — 모든 게터/세터에 자명한 Javadoc 자동 생성.
(8) 함수나 변수로 표현할 수 있다면 주석 달지 마라¶
이 장의 핵심 메시지.
(9) 위치를 표시하는 주석¶
가끔 의미 있지만 남발하면 노이즈. IDE 사용 시 거의 필요 없음.
(10) 닫는 괄호에 다는 주석¶
함수가 작으면 필요 없음. 필요하다면 함수 추출 의 신호.
(11) 공로를 돌리거나 저자를 표시하는 주석¶
→ Git blame이 함. 코드에서 즉시 제거.
(12) 주석으로 처리한 코드¶
→ 즉시 삭제. Git에 있음. "혹시 모르니" 두지 마라.
(13) HTML 주석¶
Javadoc 생성기 외에는 가독성 떨어뜨림.
(14) 전역 정보¶
기본 포트 정보가 이 메서드 주석에 있을 이유 없음 → 다른 곳에서 변경되면 어긋남.
(15) 너무 많은 정보¶
긴 역사·표준·정책 인용은 주석 영역 아님 → 별도 문서.
(16) 모호한 관계 / 함수 헤더 / 비공개 Javadoc¶
주석과 코드의 관계가 멀거나, 모든 함수에 의무 헤더, 비공개 함수에 Javadoc — 모두 노이즈.
핵심 교훈¶
- 주석은 실패의 인정. 코드가 의도를 못 말하므로 사과문이 됨.
- 함수 추출·이름 바꾸기 가 대부분의 주석을 불필요하게 만든다.
- 좋은 주석은 왜 를 설명함 (의도·경고·중요성). 나쁜 주석은 무엇 을 중복함.
- 주석은 코드와 함께 진화하지 않는다 → 시간이 지나면 거짓.
- Git 이 기억하는 정보는 코드에 두지 마라 (이력·저자).
- 공개 API Javadoc 만 예외 — 그 외는 가능한 한 적게.
함정 / 주의¶
- "주석 = 무조건 나쁨" 도그마 위험. 왜를 설명하는 주석은 좋음.
- 회사 정책상 의무적 Javadoc은 어쩔 수 없을 때 — 최소 의미 있는 내용으로.
- TODO 는 IDE 검색으로 정기 청소. 영구 TODO 는 죽은 약속.
체크리스트 (코드 리뷰용)¶
- 주석이 왜 가 아니라 무엇 을 설명하고 있는가 (= 나쁨 신호)
- 함수·변수 이름으로 옮길 수 있는 주석인가
- 코드가 변경됐는데 주석은 옛 정보인가
- 주석으로 처리된 죽은 코드가 있는가 → 즉시 삭제
- 이력·저자 주석이 있는가 → 즉시 삭제 (Git이 기억)
- 의무적 Javadoc이 자명한 매개변수만 나열하는가
- 공개 API에 Javadoc이 누락되어 있는가 (Item 56)
퀴즈¶
Q1. "주석은 나쁜 코드를 보완하지 못한다" 의 의미는?
A. 코드가 엉망일 때 주석을 추가해서 가독성을 만회하려 하지 말고, 코드 자체를 고쳐라. 주석은 사과문일 뿐. 결국 코드가 변하면 주석은 거짓이 됨.
Q2. "왜" 와 "무엇" 중 주석이 설명해야 할 것은?
A. 왜. 무엇은 코드 자체로 보여야 함 (이름·구조). 왜는 코드가 표현 못 하는 영역 — 정책, 외부 제약, 과거 사고 회피, 결정의 배경.
Q3. Javadoc이 4장에서 거의 유일하게 살아남는 좋은 주석인 이유?
A. 공개 API는 외부 사용자에게 계약 을 명시해야 하기 때문. 함수 이름만으로는 매개변수 nullable·예외 조건·반환값 의미를 다 말할 수 없음. Effective Java Item 56과 같은 결.
Q4. "이력·저자 주석" 을 즉시 삭제해도 되는 이유?
A. Git이 더 정확하고 자동으로 기억. 코드 안 주석은 갱신 안 되어 거짓이 되기 쉬움. git log / git blame 이 답.
Q5. 주석 처리된 죽은 코드를 "혹시 모르니" 두면 안 되는 이유?
A. Git에 있어서 언제든 복구 가능. 코드 안에 남아 있으면 (1) 읽는 사람의 인지 부담, (2) "왜 주석 처리됐는지" 추적 비용, (3) 실수로 살려낼 위험.
다음 장 예고 — 5장: 형식 맞추기¶
코드의 세로·가로 형식 의 규칙. "신문 기사처럼 작성하라" — 상위 개념이 위, 세부가 아래. 짧은 장이지만 팀 일관성의 기반.