클린코드 스터디 - 017
17장 냄새와 휴리스틱
- 휴리스틱(heuristics) 또는 발견법(發見法)이란 불충분한 시간이나 정보로 인하여 합리적인 판단을 할 수 없거나, 체계적이면서 합리적인 판단이 굳이 필요하지 않은 상황에서 사람들이 빠르게 사용할 수 있는 어림짐작의 방법이다.
마틴 파울러의 Refactoring 에서 코드냄새라는 것을 거론한다.
-
리스트
리펙토링이란? 외부동작을 바꾸지 않으면서 내부 구조를 개선하는 방법
주석
부적절한 정보 : 소스 관리시스템, 이슈추적 등 은 주석으로 적절하지 못하다. 작성자, 최종수정일, 문제번호 등만 메타주석으로 넣는다.
쓸모 없는 주석 : 오래된 주석, 엉뚱한 주석, 잘못된 주석은 쓸모 없음. 즉 쓸모없어질 주석은 아예 안다는것이 낫다.
중복된 주석 : 코드만으로 설명이 가능함에도 불구하고 구구절절 설명하는 주석이 중복된 주석이다.
성의 없는 주석 : 잘 작성 하기 위해 시간을 들여서 멋지게 작성하고 신중한 단어를 통해 작성하자. 쓸데없는소리 x
주석 처리된 코드: 주석처리된 코드는 오래된 코드인지 중요한 코드인지 알길이 없으므로 주석으로 처리된 코드는 흉물이다.
환경
여러단계로 빌드해야한다. : 빌드는 한단계로 소스관리시스템에서 이것저것 체크아웃을 안하도록 한번의 명령으로 가능하도록 해야한다.
여러단계로 테스트해야한다. : 모든 단위테스트는 한 명령으로 즉 IDE에서 버튼하나로 모든 테스트를 돌리도록 해야한다.
함수
너무 많은 인수 : 인수의 개수는 작을수록 좋다.
출력인수: 일반적으로 독자는 인수를 입력으로 간주
플래그인수: 플래그 인수는 혼란이 있으므로 최대한 피해라.
죽은함수 : 아무도 호출하지 않는 함수는 삭제해라
일반
한 소스 파일에 여러 언어사용 : 혼란스럽거나 조잡해진다 한개만 써라
당연한 동작을 구현하지 않는다. : 즉 문자열을 enum으로 바꾸는 쓸데없는 동작을 만들지 않음
경계를 올바로 처리하지 않는다. : 경계 조건을 테스트하는 테스트 케이스를 처리해라.
안전절차 무시: 컴파일러의 경고에 맞춰 안전을 지키자
중복 : DRY : Don’t Repeat YourSelf, Once and Only Once 한번 단 한번만, 등 중복을 발견하면 추상화할 기회로 간주하고 중복된 루틴과 클래스를 분리하라.
추상화 수준이 올바르지 못하다. : 추상화 할 때 저차원 개념은 파생클래스에 넣고 고차원 개념은 기초클래스에 넣어라.
기초클래스가 파생클래스에 의존한다. : 파생클래스는 기초클래스를 아예 몰라야 한다.
과도한 정보: 인터페이스를 분리해라 (ISP)
죽은 코드 : 죽은 함수와 동일하게 실행하지 않는 코드
수직 분리: 최대한 사용하는 위치에 가깝게 정의
일관성 부족: 특정방식을 통해 구현하면 유사한 개념도 비슷한 방식으로 구현하라.
잡동사니 : 빈 기본생성자 지워라(잡동사니를 지워라)
인위적 결합 : 서로 무관한 개념은 결합하지 말아라 (enum은 특정 클래스에 속할 필요 없음)
기능욕심 : 클래스 메서드는 자기의 클래스 변수와 함수에만 관심을 가져라
선택자 인수: 인수를 넘겨 동작을 선택하는것보다 새로운 함수를 만들어라.
ex) isExist()
모호한 의도 : 코드를 짤때는 의도를 명확하게 밝혀라
잘못 지운 책임: 코드는 독자가 자연스럽게 기대할 위치에 배치해야한다.
부적절한 static 함수 : static 함수보다 인스턴스 함수가 더 좋으므로 의심된다면 인스턴스 함수로 정의해라.
서술적변수 : 계산을 여러단계로 나누고 중간값으로 서술적인 변수를 사용해라.
이름과 기능이 일치하는 함수 : Date.add 보단 addDaysTo라는 이름이 낫다.
알고리즘을 이해하라 : 기능이 뻔히 보이도록 함수를 깔끔하게 짜라
논리적 의존성은 물리적으로 드러내라. : 책임질 정보를 당연히 알거라고 생각하는 가정 자제
if/else 혹은 switch case보다 다형성을 이용하라. : 다형성 객체를 생성해 switch문 대신
표준 표기법을 따라라. : 컨벤션을 따라라
매직 숫자는 명명된 상수로 교체 : 특정 숫자로 교체해라
정확하라 : 통화를 사용한다면 정수를 사용하는것과 같이 기본적으로 사용
관례보다는 구조를 사용하라. 추상클래스로 필요한것을 강제
조건을 캡슐화하라 :
if (shouldBeDeleted(timer)) 보단if (timer.hasExpired() && !timer.isRecurrent())
부정조건을 피하라.
함수는 한가지만 해라 .
숨겨진 시각적인 결합: 호출 순서대로 배치
일관성을 유지하라 : 이름과 코드를 일관적으로 짜라
경계조건을 캡슐화 하라 : +1를 흩어 놓지 않는다.
함수의 추상화수준을 한 단계만 내려가야한다.
*참고 : Logical Thinking
설정정보는 최상위 단계에 둬라 : 상수의 설정정보 등은 최상위에 둬라
추이적 탐색을 피하라 : 모듈은 주변 모듈을 모를수록 좋다.
자바
import 긴 목록 피하고 wild card 사용하라
상수는 상속하지 않는다.
상수 vs Enum enum 써라
이름
서술적인 이름써라
적절한 추상화수준에서의 이름 선택해라
표준명명법을 써라 (패턴쓸경우 패턴이름 뒤에붙이는형태)
명확한이름
긴 범위는 긴 이름을 사용해라
인코딩을 피하라
이름으로 부수효과를 설명하라.
테스트
불충분한 테스트
커버리지 도구
테스트 건너뛰지 마라
무시한 테스트는 모호함이다.
경계조건을 테스트하라.
버그 주변은 철저히 테스트해라
실패 케이스를 만들어라
테스트 커버리지 패턴을 살펴라
빠르게 테스트 해야한다.