책을 읽게 된 배경
어떻게 하면 개발 생산성을 높일 수 있을까? 어떤게 좋은 코드일까? 이해하기 쉽고 읽기 쉬운 코드는 어떻게 작성해야할까? 등을 고민하다가 이 책을 읽게 됐다.
책 소개
이 책은 깨끗한 코드를 작성할 수 있게 해주는 지침서이다. 580여 페이지, 가격은 2만 6천원정도이다. 이 책은 가볍게 읽고 넘어가는 책이 아니라, 저자의 팀이 생각하기에 좋은 코드에 대한 명확한 답과 규칙을 제시하고 이를 따르기를 원한다. 모든 규칙을 전부 지킬 필요는 없지만, 많은 시행착오 끝에 도달한 결론인 만큼 규칙의 배경을 잘 이해하고 따르면 좋은 코드를 작성하는데 도움이 될 거라 생각한다.
목차
1장. 깨끗한 코드
- 코드가 존재하리라
- 나쁜 코드
- 나쁜 코드로 치르는 대가
- 우리들 생각
- 우리는 저자다
- 보이스카우트 규칙
- 프리퀄과 원칙
- 결론
핵심 정리
- 나쁜 코드는 더 나쁜 코드를 양산한다. 결국 생산성이 떨어지고 프로그램을 수정하는게 불가능해진다.
- 깨끗한 코드를 유지하는 간단한 방법: 보이스카우트 규칙 "캠프장을 처음 왔을 때보다 더 깨끗하게 해놓고 떠나라"
- 좋은 이름을 지으려면 시간이 걸리지만 좋은 이름으로 절약하는 시간이 훨씬 더 많다. 좋은 이름은 코드를 이해하기 쉽게 만들어준다.
2장. 의미 있는 이름
- 의도를 분명히 밝혀라
- 그릇된 정보를 피하라
- 의미 있게 구분하라
- 발음하기 쉬운 이름을 사용하라
- 검색하기 쉬운 이름을 사용하라
- 인코딩을 피하라
- 자신의 기억력을 자랑하지 마라
- 클래스 이름
- 메서드 이름
- 기발한 이름은 피하라
- 한 개념에 한 단어를 사용하라
- 말장난을 하지 마라
- 해법 영역에서 가져온 이름을 사용하라
- 문제 영역에서 가져온 이름을 사용하라
- 의미 있는 맥락을 추가하라
- 불필요한 맥락을 없애라
핵심 정리
- 의도를 분명히 밝혀라
- 그른됫 정보를 피하라
- 의미 있게 구분하라
- 발음하기 쉬운 이름을 사용하라
- 검색하기 쉬운 이름을 사용하라
- 인코딩을 피하라
- 자신의 기억력을 자랑하지 마라
- 클래스 이름: 명사나 명사구
- 메서드 이름: 동사나 동사구
- 기발한 이름을 피하라
- 한 개념에 한 단어를 사용하라
- 말장난을 하지 마라
- 해법 영역에서 가져온 이름을 사용하라
- 문제 영역에서 가져온 이름을 사용하라
- 의미 있는 맥락을 추가하라
- 불필요한 맥락을 없애라
3장. 함수
- 작게 만들어라!
4줄 이하의 짧은 함수가 좋다.
- 한 가지만 해라!
함수는 한가지 일에 집중해야한다.
- 함수 당 추상화 수준은 하나로!
추상화가 높을수록 복잡한 동작을 하는 함수다. 추상화 수준을 같게 맞춰야 함수를 읽기 좋다.
- Switch 문
여러 함수에서 같은 조건문이 반복되면 클래스의 추상 팩토리 안으로 조건문을 숨긴다.
- 서술적인 이름을 사용하라
함수의 이름이 곧 함수의 동작이어야 한다.
- 함수 인수
인수는 적을수록 좋다.
- 플래그 인수
플래그 인수는 함수가 2가지 동작을 한다는걸 의미한다.
- 부수 효과를 일으키지 마라!
부수 효과는 거짓말과 같다.
- 명령과 조회를 분리하라!
- 오류 코드보다 예외를 사용하라!
try/catch를 사용하고 try/catch를 함수로 뽑아내자
- 반복하지 마라!
중복 코드를 제거해서 불필요한 수정을 줄여라
- 구조적 프로그래밍
입구(인자)와 출구(리턴)를 하나로 둔다.
- 함수를 어떻게 짜죠?
함수를 짜는건 글짓기와 같다. 처음엔 긴 코드를 작성하고, 테스트를 작성한 후, 여기저기 고쳐가며 좋은 함수를 만든다.
- 결론
함수는 글의 동사이며, 클래스는 명사다. 길이가 짧고, 이름이 좋고, 체계가 잡힌 함수를 만들어야한다. 하지만 진짜 목표는 이야기를 풀어나가는데 있다는 사실을 명심해야한다.
4장. 주석
- 나쁜 코드에 주석을 달지 마라. 새로 짜라. - 브라이언 W. 커니핸, P.J. 플라우거
- 주석은 나쁜 코드를 보완하지 못한다
- 코드로 의도를 표현하라!
- 좋은 주석
법적인 주석
정보를 제공하는 주석
의도를 설명하는 주석
의미를 명료하게 밝히는 주석
결과를 경고하는 주석
TODO 주석
중요성을 강조하는 주석
- 나쁜 주석
주절거리는 주석
같은 이야기를 중복하는 주석
오해할 여지가 있는 주석
의무적으로 다는 주석
이력을 기록하는 주석
있으나 마나 한 주석
무서운 잡음
함수나 변수로 표현할 수 있다면 주석을 달지 마라
위치를 표시하는 주석
닫는 괄호에 다는 주석
공로를 돌리거나 저자를 표시하는 주석
주석으로 처리한 코드
HTML 주석
전역 정보
너무 많은 정보
모호한 관계
함수 헤더
5장. 형식 맞추기
- 형식을 맞추는 목적
코드의 가독성은 코드의 품질에 지대한 영향을 미친다.
- 적절한 행 길이를 유지하라
신문 기사처럼 작성하라
이름을 신중히 정하고, 중요로직, 세세한 설명 순서로 작성한다.
개념은 빈 행으로 분리하라
빈 행을 넣으면 서로 다른 개념을 쉽게 구분할 수 있다.
세로 밀집도: 연관성
연관성이 있는 코드는 가까이에 모아둔다.
수직 거리
- 변수 선언
사용하는 위치에 최대한 가깝게
- 인스턴스 변수
맨 처음에 선언한다. 가장 마지막에 선언하기도 한다.
- 종속 함수
호출하는 함수를 먼저 배치한다.
- 개념적 유사성
비슷한 코드는 모아둔다. 오버로딩 함수
- 가로 형식 맞추기
행길이 80~120자
가로 공백과 밀집도
연산자 앞뒤는 공백으로 띄어쓴다.
- 가로 정렬
변수 선언부에 탭이나 띄어쓰기로 세로줄을 맞춰서 정렬하는건 변수명만 읽게 되므로 좋지 않다.
들여쓰기
가짜 범위
중괄호로 범위를 명시한다
- 팀 규칙
개인 규칙보다 팀 규칙을 따른다.
- 밥 아저씨의 형식 규칙
코드 자체가 최고의 구현 표준 문서가 돼야한다
6장. 객체와 자료 구조
- 자료 추상화
클래스는 get/set함수가 아닌 추상적인 개념으로 표현하도록 고민해야한다.
- 자료 구조/객체 비대칭
자료 구조는 자료를 그대로 공개하며 별다른 함수는 제공하지 않는다.
객체는 추상화 뒤로 자료를 숨긴 채 자료를 다루는 함수만 공개한다.
상황에 따라 적합한 방식을 고른다.
- 디미터 법칙
기차 충돌
잡종 구조
구조체 감추기
객체로 내부를 잘 추상화해서 제공하자
- 자료 전달 객체(DTO)
활성 레코드: 자료구조로 취급하고 내부 자료를 숨기는 객체는 따로 생성한다.
- 결론
객체는 동작을 공개하고 자료를 숨긴다. 자료구조는 자료를 노출한다. 새로운 자료타입을 추가하는 유연성이 필요하면 객체가 적합하다. 새로운 동작을 추가하는 유연성이 필요하면 자료 구조가 적합하다.
7장. 오류 처리
- 흩어진 오류 처리 코드 때문에 실제 코드가 하는 일을 파악하기가 불가능해지는 경우가 많다.
- 오류 코드보다 예외를 사용하라
함수를 호출한 즉시 오류를 처리하려고 하면 잊어버리기 쉽다. 그래서 오류가 발생하면 throw 하는게 낫다. 그러면 논리 코드와 오류처리 코드가 섞이지 않는다.
- Try-Catch-Finally 문부터 작성하라
예외가 발생할 코드를 짤때 미리 try-catch문을 작성하면 상태를 정의하기 쉬워진다.
- 미확인(unchecked) 예외를 사용하라
자바 프로그래머들은 메서드를 선언할때 모든 예외를 열거했었다. 하지만 이 방법은 하위 메서드의 예외가 상위 메서드에 영향을 주므로 OCP 원칙을 위반한다. 모든 예외를 관리하는 비용이 크기에 꼭 필요한 경우가 아니라면 미확인 예외 처리방식이 낫다.
- 예외에 의미를 제공하라
예외에 오류 메시지 정보를 담아 함께 던진다.
- 호출자를 고려해 예외 클래스를 정의하라
외부 API를 감싸는 클래스를 하나 만들어서 프로그램에 맞는 예외를 던지도록 한다. 감싸기 기법을 사용하면 특정 업체가 API를 설계한 방식에 발목 잡히지 않는다.
- 정상 흐름을 정의하라
때로는 중단이 적합하지 않은 때도 있다. 예외가 논리를 따라가기 어려운 경우
- null을 반환하지 마라
null을 참조하려 할때 NullPointerException이 발생하는데 이 예외를 매번 잡아주는건 코드를 지저분하게 만든다. null을 반환하기보다 빈배열 등을 반환해서 불필요한 익셉션 코드를 제거하자.
- null을 전달하지 마라
null을 파라미터로 전달하면 함수 내부에서 널익셉션이 발생할 수 있다. 널을 처리하기 위한 불필요한 처리기가 필요해진다.
- 결론
오류 처리를 프로그램 논리와 분리하면 독립적인 추론이 가능해지며 코드 유지보수성도 크게 높아진다.
여기까지 읽었다. 구글엔지니어 책을 먼저 다 읽고 클린 코드를 다시 읽으려고 한다. 둘다 너무 좋은 책이다.
8장. 경계
9장. 단위 테스트
10장. 클래스
11장. 시스템
12장. 창발성
13장. 동시성
14장. 점진적인 개선
15장. JUnit 들여다보기
16장. SerialDate 리팩터링
17장. 냄새와 휴리스틱
부록 A. 동시성 II
부록 B. org.jfree.date.SerialDate
부록 C. 휴리스틱의 교차 참조 목록