[CleanCode 17장] 냄새와 휴리스틱

soyeon·2022년 8월 17일
0

CleanCode

목록 보기
17/18
post-thumbnail

주석

부적절한 정보

주석은 소스코드에 관련된 정보가 들어있어야 한다. 다른 시스템의 정보가 들어있으면 적절하지 못하다.

쓸모 없는 주석

쓸모 없어질 것 같은 주석은 달지 않는 것이 좋다. 쓸모 없어진 주석은 빠르게 삭제해야 한다. 쓸모 없는 주석은 코드를 잘못된 방향으로 이끈다.

중복된 주석

주석으로는 코드만으로 설명을 다하지 못할 때만 사용한다.

성의 없는 주석

주석을 작성하려면 시간을 들여서 간결하고 명료하게 작성해야 한다.

주석 처리된 코드

주석으로 처리된 코드는 바로 지워버려야 한다.

환경

여러 단계로 빌드해야 한다

한 명령으로 빌드할 수 있어야 한다.

여러 단계로 테스트해야 한다

명령 하나로 모든 테스트를 한 번에 실행 할 수 있어야 한다.

함수

너무 많은 인수

함수에서 인수는 가능한 적게 한다.

출력 인수

출력인수를 쓰기보다는 함수가 속한 객체의 상태를 변경하도록 한다.

플래그 인스

boolean 인수는 함수가 여러 일을 한다는 것을 의미한다. 플래그 인수는 피하는 것이 좋다.

죽은 함수

아무도 호출하지 않는 함수는 삭제한다.

일반

한 소스 파일에 여러 언어를 사용한다

이상적으로는 한 소스 파일에서는 하나의 언어를 사용하는 것이 좋다. 최대한 줄이도록 노력해야 한다.

당연한 동작을 구현하지 않는다

당연한 동작은 꼭 구현해야 한다. 이를 구현하지 않으면 사용자가 신뢰를 하지 않게 된다.

경계를 올바로 처리하지 않는다

경계 조건을 모두 찾아내고, 모든 경계 조건을 테스트하는 테스트 케이스를 작성해야 한다.

안전 절차 무시

안전 절차를 무시하면 위험하다. 자칫하면 끝없는 디버깅에 시달릴 수 있다.

중복

코드에서 중복을 발견하면 추상화할 기회로 생각한다. 다른 클래스로 분리하는 것이 좋다. 어디서든 중복을 발견하면 없애야 한다.

추상화 수준이 올바르지 못하다

추상화로 개념을 분리할 떄는 조심해야 한다. 저차원 개념은 파생 클래스로, 고차원 개념은 기초 클래스에 넣는다.

기초 클래스가 파생 클래스에 의존한다

기초 클래스가 파생 클래스를 사용하면 안된다. 기초 클래스는 파생 클래스를 아예 몰라야 한다.

과도한 정보

인터페이스를 작게, 깐깐하게 만들어서 결합도를 낮춘다.

죽은 코드

실행되지 않는 코드를 발견하면 시스템에서 제거한다.

수직 분리

변수와 함수는 사용되는 위치와 가깝게 정의한다.

일관성 부족

어떤 개념을 특정 방식으로 구현했다면 유사한 개념도 같은 방식으로 구현해야 한다. 이렇게 하면 코드를 읽고 수정하는 것이 수월해진다.

잡동사니

비어 있는 기본 생성자, 사용하지 않는 변수, 호출하지 않는 함수 등은 제거해야 한다.

인위적 결합

서로 무관한 개념을 인위적으로 결합하지 않는다. 함수, 상수, 변수를 선언할 때 아무 곳에나 선언하면 안 된다.

기능 욕심

클래스 메서드는 다른 클래스의 변수나 함수에 관심을 가져서는 안된다.

선택자 인수

선택자 인수는 목적을 기억하기 어렵기 때문에 사용하지 않는 것이 좋다.

모호한 의도

코드에 의도를 분명히 밝혀야 한다.

잘못 지운 책임

코드를 배치할 때, 올바른 곳에 배치해야 한다.

부적절한 static 함수

static 함수를 정의할 때는 재정의 할 필요가 없는지 따져보고 설정한다.

서술적 변수

서술적 변수를 사용하면 프로그램 가독성을 높일 수 있다. 모듈이 읽기 쉬워진다.

이름과 기능이 일치하는 함수

이름만으로 기능이 분명하지 않으면 더 좋은 이름을 붙이도록 변경해야 한다.

알고리즘을 이해하라

알고리즘이 올바르다는 사실을 확인한 후에 함수를 재구성한다.

논리적 의존성은 물리적으로 드러내라

한 모듈이 다른 모듈에 의존한다면 물리적인 의존성도 있어야 한다. 의존하는 모든 정보를 명시적으로 요청하는 것이 좋다.

If/Else 혹은 Switch/Case 문보다 다항성을 사용하라

switch를 사용하기 전에 다형성을 먼저 고려한다.

표준 표기법을 따르라

구현 표준을 따라야 한다. 팀이 정한 표준을 팀원 모두가 따른다.

매직 숫자는 명명된 상수로 교체하라

일반적으로 코드에 숫자를 사용하지 않는다. 숫자는 명명된 상수 뒤로 숨겨야 한다.

정확하라

코드에서 무언가를 결정할 때는 정확히 결정해야 한다. 결정을 내리는 이유와 예외를 처리할 방법을 정확히 알고 있어야 한다.

관례보다 구조를 사용하라

설계 결정을 강제할 때는 규칙보다 관례를 사용한다. 명명 관례도 좋지만 구조 자체를 강제하면 좋다.

조건을 캡슐화하라

부울 논리보다는 조건의 의도를 분명히 밝히는 함수로 표현한다.

부정 조건은 피하라

부정 조건이 긍정 조건보다 이해하기 어렵다. 가능한 긍정 조건으로 표현한다.

함수는 한 가지만 해야 한다

함수는 한 가지만 수행하도록 작은 함수로 나눈다.

숨겨진 시간적인 결합

함수의 시간적인 결합을 숨겨서는 안된다. 함수가 호출되는 순서를 명백하기 드러낸다.

일관성을 유지하라

코드 구조에 일관성이 깨지기 않게 한다.

경계 조건을 캡슐화하라

경계 조건은 캡슐화하여 빼먹지 않게 한다.

함수는 추상화 수준을 한 단계만 내려가야 한다.

함수 안에서 모든 문장은 추상화 수준이 동일해야 한다. 추상화 수준은 함수 이름이 의미하는 작업보다 한 단계만 낮아야 한다.

설정 정보는 최상위 단계에 둬라

추상화 최상위 단계에 둬야 할 기본값 상수나 설정 관련 상수를 저차원 함수에 숨겨서는 안된다.

추이적 탐색을 피하라

한 모듈은 주변 모듈을 모를수록 좋다. 모듈들은 자신이 사용하는 모듈만 알아야 한다.

자바

긴 import 목록을 피하고 와일드카드를 사용하라

패키지 안에서 클래스를 둘 이상 사용한다면 와일드카드를 사용해 패키지 전체를 가져오도록 한다.

상수는 상속하지 않는다

상수는 상속하지 않고, static import를 사용하도록 한다.

상수 대 Enum

enum은 상수보다 유연하고 서술적인 강력한 도구이다. 마음껏 활용하도록 한다.

이름

서술적인 이름을 사용하라

이름은 성급하게 정하지 않고, 서술적인 이름으로 신중하게 고른다.

적절한 추상화 수준에서 이름을 선택하라

구현을 드러내는 이름은 피하도록 한다. 클래스나 함수가 위치하는 추상화 수준을 반영하는 이름을 선택한다.

가능하다면 표준 명명법을 사용하라

기존 명명법을 사용하는 이름은 이해하기 더 쉽다.

명확한 이름

함수나 변수의 목적을 정확히 밝히는 이름을 선택한다.

긴 범위는 긴 이름을 사용하라

이름의 길이는 범위의 길이에 비례해야 한다. 범위가 5줄 안팎이라면 i나 j처럼 짧게 지어도 괜찮다.

인코딩을 피하라

이름에 유형 정보나 범위 정보를 넣어서는 안된다.

이름으로 부수 효과를 설명하라

함수, 변수, 클래스가 하는 일을 모두 기술하는 이름을 사용한다.

테스트

불충분한 테스트

테스트는 깨질 만한 부분을 모두 테스트해야 한다.

커버리지 도구를 사용하라

테스트가 빠뜨리는 공백을 알려준다. 테스트가 불충분한 부분을 찾아낸다.

사소한 테스트를 건너뛰지 마라

사소한 테스트는 짜기 쉽다. 사소한 테스트여도 건너뛰어서는 안된다.

무시한 테스트는 모호함을 뜻한다

요구사항이 불분명할 때는 테스트 케이스를 주석으로 처리한다.

경계 조건을 테스트하라

경계 조건에서는 특별히 신경써서 테스트한다.

버그 주변은 철저히 테스트하라

버그는 서로 모이는 경향이 있기 때문에 버그 주변은 철저히 테스트한다.

실패 패턴을 살펴라

실패하는 패턴으로 문제를 진단할 수 있다.

테스트 커버리지 패턴을 살펴라

통과하는 테스트가 실행하거나 실행하지 않는 코드를 보면 실패 테스트 케이스의 원인을 알아낼 수 있다.

테스트는 빨라야 한다

테스트는 빠르게 실행되어야 한다.

0개의 댓글