17장. 냄새와 휴리스틱
쓸모 없는 것들에 대해 적어본다.
주석
- C1(부적절한 정보): 다른 시스템에 저장할 정보는 주석으로 남기지 말자.
- C2(쓸모 없는 주석): 주석은 빨리 낡기 때문에 쓸모없어질 주석이다.
- C3(중복된 주석): 코드만으로 충분한데 구구절절 설명하는 주석은 필요없다.
- C4(성의 없는 주석): 말 그대로다. 성의없는 주석들은 지우자.
- C5(주석으로 처리된 코드):
git
과 같은 소스코드 관리 프로그램 덕에 필요 없다.
환경
- E1(여러 단계 빌드): 빌드는 간단히 한 단계로 끝나야 한다.
- E2(여러 단계 테스트): 모든 단위 테스트는 한 명령으로 돌려야 한다.
함수
- F1(너무 많은 인수): 함수의 인수 개수는 작을수록 좋다. 아예 없으면 가장 좋다.
- F2(출력 인수): 함수에서 뭔가의 상태를 변경해야 한다면 함수가 속한 객체의 상태를 변경하자.
- F3(플래그 인수): boolean 인수는 함수가 여러 기능을 수핸한다는 명백한 증거다. 플래그 인수는 가능하면 피하자.
- F4(죽은 함수): 아무도 호출하지 않는 함수는 삭제하자.
git
이 모두 기억하니까 유지할 필요가 없다.
일반
- G1(소스파일 당 언어 하나): 한 소스파일에 언어 하나만 사용하자.
jsp
와 같이 여러 언어가 한번에 사용되는 경우는 피하자. - G2(특이한 동작을 하는 기능): 프로그래머가 당연하게 여길만하도록(코드를 볼 일이 없도록) 직관적으로 동작과 기능을 구현하자.
- G3(올바르지 안은 경계): 모든 경계 조건을 찾아내고, 모든 경계 조건을 테스트하는 테스트 케이스를 작성하자.
- G4(안전 절차 무시): 컴파일러 경고와 같은 안전 절차를 무시하지 말자.
- G5(중복): 중복 제거! 더 말할 필요가 있을까? 중복은 가능하면 무조건 제거하자.
- G6(추상화 수준): 제대로 된 추상화를 하자. 기초 클래스에 유틸리티 함수를 넣으면 안되듯이 말이다.
- G7(부모 클래스의 자식 의존): 부모 클래스가 자식 클래스를 모르게 하자. 의존성이 생기면 안된다.
- G8(과도한 정보): 인터페이스를 매우 작게 그리고 매우 깐깐하게 만들자. 정보를 제한해 결합도를 낮추자.
- G9(죽은 코드): 실행이 불가능한 조건(항상 false라던가...)을 가진 죽은 코드는 제거하자.
- G10(수직 분리): 변수와 함수는 사용되는 위치에 가깝게 정의해야 한다.
- G11(일관성 부족): 표기법을 일관성 있게 통일하자.
- G12(잡동사니): 비어 있는 기본 생성자와 같은 코드들은 제거하자.
- G13(인위적 결합): 서로 무관한 개념을 인위적으로 결합하지 말자. 함수, 상수, 변수를 선언할 때는 시간을 들여 올바른 위치를 고민하자.
- G14(기능 욕심): 클래스 메서드는 다른 클래스의 변수와 함수에 관심을 가지면 안된다.
- G15(선택자 인수): boolean과 같은 선택자 인수는 사용하지 말자.
- G16(모호한 의도): 코드를 짤 때는 의도를 최대한 분명히 밝힌다.
- G17(잘못 지운 책임): 코드 배치할 위치, 함수명 등 다른 사람이 보아도 명확히 이해가 가게 하자.
- G18(부적절한 static 함수): 함수를 재정의할 가능성이 존재하면 static으로 선언하지 말자.
- G19(서술적 변수): 계산을 여러 단계로 나누고 중간 값으로 서술적인 변수 이름을 사용하자. 재사용을 안하더라도 말이다.
- G20(이름과 기능이 일치하는 함수): 내부 구현을 살피거나 문서를 뒤적이지 않도록 이름을 짓자. 이름을 짓기 어려우면 짓기 쉽게 기능을 정리하자.
- G21(알고리즘을 이해하라): 기능이 뻔히 보일 정도로 함수를 깔끔하고 명확하게 재구성하자.
- G22(논리적 의존성은 물리적으로 드러내라): 의존하는 모듈이 상대 모듈에 대해 뭔가를 가정하면(논리적으로 의존하면) 안된다.
- G23(다형성을 사용하자): 가능하면 다형성을 사용하여 구현하고 switch문은 한 번만 사용하도록 만들자.
- G24(표준 표기법): 네이밍 방법, 괄호 위치 등 팀이 정한 표준을 따르자.
- G25(숫자는 상수로 교체하라): 코드에 숫자를 직접 작성하지 말고 상수로 만들어서 사용하자.
- G26(정확하라): 코드에서 뭔가를 결정할 때는 정확히 결정하자. 결정을 내리는 이유와 예외처리 방법을 분명하게 알고 하자.
- G27(관례보다 구조): 설계 섲렁을 강제할 때는 규직보다 관례를 사용하자. 명명 관례도 좋지만 구조 자체로 강제하면 더 좋다.
- G28(조건을 캡슐화하라): 부울 논리는 조건의 의도를 분명히 밝히는 함수로 표현하자.
- G29(부정 조건은 피하라): 가능하면 부정 조건 대신 긍정 조건을 사용하자.
- G30(함수는 한 가지만): 함수는 한 가지의 기능만 수행해야 한다.
- G31(숨겨진 시간적인 결합): 시간적인 결합이 필요한 함수들은 의존성을 강화해서라도 실행 순서를 확실하게 할 수 있도록 하자.
- G32(일관성을 유지하라): 코드 구조를 잡을 떄는 이유를 고민하고 그 이유를 코드 구조로 명백하게 표현하자.
- G33(경계 조건을 캡슐화하라): 경계 조건은 캡슐화하여 한 곳에서 별도로 처리할 수 있게 하자.
- G34(추상화 수준은 한 단계만 내려가게 하자): 추상화 수준은 함수 이름이 의미하는 작업보다 한 단계만 낮아야 한다.
- G35(설정 정보는 최상위 단계에 둬라): 설정은 최상위에 두어야 변경하기도 쉽다.
- G36(추이적 탐색을 피하라): 내가 아는 모듈이 연이어 자신이 아는 모듈을 따라가며 시스템 전체를 휘젓게 하지 말자.