
주석
C1: 부적절한 정보
- 작성자, 최종 수정일, PR 등과 같은 메타 정보만 주석으로 넣는다.
C2: 쓸모없는 주석
C3: 중복된 주석
C4: 성의 없는 주석
- 간결하고 명료하게 작성한다.
- 주석을 달 참이라면 시간들여 최대한 멋지게 작성해야한다.
C5: 주석 처리된 코드
- 주석으로 처리된 코드를 발견하면 즉각 지워라!
환경
E1: 여러 단계로 빌드해야 한다.
- 한 명령으로 전체를 체크아웃 해서 한 명령으로 빌드할 수 있어야 한다.
E2: 여러 단계로 테스트해야 한다.
- 모든 단위 테스트는 한 명령으로 돌려야 한다.
함수
F1: 너무 많은 인수
- 함수에서 인수 개수는 적을수록 좋다.
- 아예 없으면 가장 좋다.
F2: 출력 인수
- ❌ 출력 인수를 쓰지 말자.
- 함수에서 뭔가의 상태를 변경해야 한다면, 함수가 속한 객체의 상태를 변경한다.
F3: 플래그 인수
F4: 죽은 함수
일반
G1: 한 소스 파일에 여러 언어를 사용한다.
- 이상적으로는 소스 파일 하나에 언어 하나만 사용하는 방식이 가장 좋다.
G2: 당연한 동작을 구현하지 않는다.
- 함수나 클래스는 다른 개발자가 당연하게 여길 만한 동작과 기능을 제공해야만 한다!
G3: 경계를 올바로 처리하지 않는다.
- 코드는 올바르게 동작해야 한다.
- 모든 경계 조건을 찾아내고, 모든 경계 조건을 테스트하는 테스트 케이스를 작성하라!
G4: 안전 절차 무시
G5: 중복
- DRY
- 코드에서 중복을 발견할 때마다 추상화할 기회로 간주하라.
G6: 추상화 수준이 올바르지 못하다.
- 추상화는 저차원 상세 개념에서 고차원 일반 개념을 분리한다.
- 모든 저차원 개념은 파생 클래스에 넣고, 모든 고차원 개념은 기초 클래스에 넣는다.
- ❌ 고차원 개념과 저차원 개념을 섞어서는 안 된다.
- 세부 구현과 관련한 상수, 변수, 유틸리티 함수는 기초 클래스에 넣으면 안된다.
G7: 기초 클래스가 파생 클래스에 의존한다.
- 고차워 기초 클래스 개념을 저차원 파생 클래스 개념으로부터 분리해 독립성을 보장하기 위해서다.
- 일반적으로 기초 클래스는 파생 클래스를 아예 몰라야 마땅하다.
G8: 과도한 정보
- 잘 정의된 인터페이스는 많은 함수를 제공하지 않는다.
- 클래스가 제공하는 메서드 수는 작을수록 좋다.
- 변수 수도 작을수록 좋다.
- 인스턴스 변수 수도 작을수록 좋다.
G9: 죽은 코드
- 죽은 코드란 실행되지 않는 코드를 가리킨다.
- 불가능한 조건을 확인하는 if문
- throw문이 없는 try문에서 catch 블록
- 아무도 호출하지 않는 유틸리티 함수
- 반드시 제거하라!
G10: 수직 분리
- 변수와 함수는 사용되는 위치에 가깝게 정의한다.
- 정의하는 위치와 호출하는 위치를 가깝게 유지한다.
G11: 일관성 부족
- 표기법은 신중하게 선택하며, 일단 선택한 표기법은 신중하게 따른다.
G12: 잡동사니
- 🧹 소스 파일은 언제나 깔끔하게 정리하라!
- 비어있는 기본 생성자
- 아무도 사용하지 않는 변수
- 아무도 호출하지 않는 함수
- 정보를 제공하지 못하는 주석
G13: 인위적 결합
- ❌ 서로 무관한 개념을 인위적으로 결합하지 마라.
- 함수, 상수, 변수를 선언할 때는 시간을 들여 올바른 위치를 고민한다.
G14: 기능 욕심
- ❌ 클래스 메서드는 자기 클래스의 변수와 함수에 관심을 가져야지, 다른 클래스의 변수와 함수에 관심을 가져서는 안된다!
G15: 선택자 인수 (Selector)
- 함수 호출 끝에 달리는 boolean 인수를 쓰지마라!
- ✅ 일반적으로, 인수를 넘겨 동작을 선택하는 대신 새로운 함수를 만드는 편이 좋다.
G16: 모호한 의도
- 코드를 짤 때는 의도를 최대한 분명히 밝혀라!
G17: 잘못 지운 책임
G18: 부적절한 static 함수
- 일반적으로 static 함수보다 인스턴스 함수가 더 좋다.
- 반드시 static 함수로 정의해야겠다면, 재정의할 가능성은 없는지 꼼꼼히 따져본다.
G19: 서술적 변수
- 계산을 여러 단계로 나누고 중간 값으로 서술적인 변수 이름을 사용하는 방법
G20: 이름과 기능이 일치하는 함수
date.addDaysTo(5)
, date.increaseByDays(5)
date.daysLater(5)
, date.daysSince(5)
G21: 알고리즘을 이해하라
G22: 논리적 의존성은 물리적으로 드러내라
G23: if/else 혹은 swith/case 문보다 다형성을 사용하라
G24: 표준 표기법을 따르라.
G25: 매직 숫자는 명명된 상수로 교체하라!
G26: 정확하라
G27: 관례보다 구조를 사용하라
G28: 조건을 캡슐화하라
G29: 부정 조건은 피하라
G30: 함수는 한 가지만 해야 한다.
G31: 숨겨진 시간적인 결합
- 함수 인수나 수신 객체를 적절히 배치해 함수가 호출되는 순서를 명백히 드러내라!
G32: 일관성을 유지하라
G33: 경계 조건을 캡슐화 하라
G34: 함수는 추상화 수준을 한 단계만 내려가야 한다.
G35: 설정 정보는 최상위 단계에 둬라
G36: 추이적 탐색을 피하라
자바
J1: 긴 import 목록을 피하고 와일드카드를 사용하라
- 명시적인 import문은 강한 의존성을 생성하지만, 와일드칻드는 그렇지 않다.
J2: 상수는 상속하지 않는다.
J3: 상수 vs Enum
이름
N1: 서술적인 이름을 사용하라
N2: 적절한 추상화 수준에서 이름을 선택하라
N3: 가능하다면 표준 명명법을 사용하라
N4: 명확한 이름을 사용하라
N5: 코드가 길어진다면 긴 이름을 사용하라
N6: 인코딩을 피하라
N7: 이름으로 부수 효과를 설명하라
- 함수, 변수, 클래스가 하는 일을 모두 기술하는 이름을 사용하라.
테스트
T1: 불충분한 테스트
- 테스트 케이스가 확인하지 않는 조건이나 검증하지 않는 계산이 있다면, 그 테스트는 불완전하다.
T2: 커버리지 도구를 사용하라!
T3: 사소한 테스트를 건너뛰지 마라!
T4: 무시한 테스트는 모호함을 뜻한다.
T5: 경계 조건을 테스트하라!
T6: 버그 주변은 철저히 테스트하라!
T7: 실패 패턴을 살펴라
T8: 테스트 커버리지 패턴을 살펴라
T9: 테스트는 빨라야 한다