클린 코드 실전 강의 교재¶
14장 — 점진적인 개선 (Args 사례)¶
대상: Java/Spring 백엔드 입문~중급 수강생 형식: 사례 워크스루 — 1차 초안 → 정련 → 결과 전제 환경: Java 17+
0. 이 장을 시작하기 전에¶
0.1 학습 목표¶
- 초안이 추한 건 정상, 정련이 본업.
- 점진적 개선의 실제 단계 를 사례로 본다.
- "TDD + 작은 단계 + 테스트 안전망 = 자유로운 정련" 의 살아있는 증명.
0.2 사례 — Args 라이브러리¶
명령줄 인수 파서. -l (boolean), -p 8080 (int), -d /tmp (String) 같은 옵션을 자바 API 로 변환.
Args args = new Args("l,p#,d*", argv);
boolean logging = args.getBoolean('l');
int port = args.getInt('p');
String directory = args.getString('d');
0.3 현업에서 왜 중요한가¶
- 초보의 두려움 "처음부터 깨끗하게 짜야지" 를 깨뜨림.
- 1차 초안 → 점진 정련의 사이클이 모든 클린 코드의 본질.
14.1 Args 1차 초안 — 추한 코드¶
진행¶
- 1차 초안: 약 100줄짜리 한 함수, 거대한 switch, 가변 상태, 중복 처리.
- 작동은 함. 테스트 80+ 통과.
그래서 멈췄다¶
코드가 커지면서 새 옵션 추가 = 거대 함수 곳곳 수정. 다음 기능 추가가 두려워짐 = 멈춰야 할 신호.
"변경이 두렵다" = 리팩터링 시점.
14.2 점진적으로 개선하다¶
핵심 결정 — 처음부터 다시?¶
아니오. 처음부터 다시 짜면 (1) 옛 시스템과 새 시스템 동시 유지, (2) 새 시스템도 다시 추해질 가능성.
→ 점진적 변환 — 테스트가 안전망.
단계¶
- 각 인수 타입별 클래스 추출 (BooleanArgumentMarshaler, IntegerArgumentMarshaler, ...)
- switch 제거 — 다형성으로 (entity-refactoring 10.4)
- 공통 인터페이스 추출 (
ArgumentMarshaler) - Map
로 옵션 관리 - 각 단계마다 모든 테스트 통과 확인
Before / After 개요¶
// Before — 한 함수에 모든 분기
private void parseArgument(char argChar) {
if (isBooleanArg(argChar)) parseBooleanArg(argChar);
else if (isIntegerArg(argChar)) parseIntegerArg(argChar);
else if (isStringArg(argChar)) parseStringArg(argChar);
// ... 새 타입 추가마다 분기 추가
}
// After — 다형성
private void parseArgument(char argChar) {
ArgumentMarshaler m = marshalers.get(argChar);
m.set(currentArgument); // 다형성
}
새 타입 추가 = 새 클래스 1개 + Map 등록.
14.3 결론¶
책의 교훈¶
- 초안이 추한 건 정상. 부끄러워하지 마라.
- 테스트 안전망 위에서 작은 단계로 정련.
- 다시 짜고 싶은 유혹 을 견뎌라 — 점진이 더 빠름.
- 변경이 두렵다 = 리팩터링 시점.
→ 리팩터링 책 전체의 정신과 동일.
핵심 교훈¶
- 초안이 추하다 = 정상. 부끄러워 멈추지 마라.
- 다시 짜기 vs 점진 개선 — 거의 항상 점진이 답.
- 매 단계 모든 테스트 통과 = 작은 단계의 자유.
- switch + 분기 폭증 = 다형성 신호 (entity-refactoring 10.4).
함정 / 주의¶
- 점진 개선이 "한 단계가 너무 큼" 이면 더 작은 단계로 분해.
- 테스트 없이 정련 = 도박. 1단계는 항상 테스트 부터.
- "1차 초안" 자체가 너무 거대해지면 (1,000+ 줄) 다시 짜는 게 답일 때도.
체크리스트¶
- 1차 초안 후 멈추고 정련하는 습관이 있는가
- 매 정련 단계 후 모든 테스트 통과 확인하는가
- switch + 분기가 폭증하기 전에 다형성 적용하는가
- "이 코드 다시 짜고 싶다" 가 점진 개선보다 빠른가 의심하는가
퀴즈¶
Q1. "처음부터 깨끗하게 짜는 게 어려운" 이유?
A. 요구사항·도메인을 모르면서 추상화부터 만들면 잘못된 추상화가 됨. 1차 초안 = 도메인 탐색, 2차 정련 = 좋은 추상화 발견. 코드가 진화하면서 알게 됨.
Q2. "변경이 두렵다" 가 무엇의 신호?
A. 리팩터링 시점. 두려움은 구조 문제 (결합도·중복·거대 함수) 의 증상. 그대로 두면 점점 더 두려워짐. 작게 정련하면 다시 자유.
Q3. switch + 분기 폭증을 다형성으로 옮기는 효과?
A. 새 타입 추가 = 새 클래스 1개. switch 모든 위치 수정 안 함 (산탄총 수술 회피). OCP 충족.
Q4. "다시 짜기" 가 거의 항상 답이 아닌 이유?
A. (1) 옛 시스템도 유지해야 함, (2) 옛 사용자 요구 다 잊혀짐, (3) 새 시스템도 추해질 가능성, (4) 시간 폭증. 오브젝트 의 "원대한 재설계의 꿈" 도 같은 메시지.
Q5. 14장이 책 전체에 주는 메시지?
A. 클린 코드 = 점진 정련의 결과. 1~13장의 권고는 모두 정련 단계의 도구. 처음부터 완벽한 코드 X, 추한 초안 + 정련 사이클이 본업.
다음 장 예고 — 15장: JUnit 들여다보기¶
JUnit 의 한 클래스를 함께 정련. 같은 패턴 — 작동하는 코드에서 시작 → 단계별 깨끗하게.