Chapter17. 냄새와 휴리스틱

김신영·2023년 5월 31일
0

Clean Code

목록 보기
1/1
post-thumbnail

주석

C1: 부적절한 정보

  • 작성자, 최종 수정일, PR 등과 같은 메타 정보만 주석으로 넣는다.

C2: 쓸모없는 주석

  • 주석은 빨리 낡는다.

C3: 중복된 주석

C4: 성의 없는 주석

  • 간결하고 명료하게 작성한다.
  • 주석을 달 참이라면 시간들여 최대한 멋지게 작성해야한다.

C5: 주석 처리된 코드

  • 주석으로 처리된 코드를 발견하면 즉각 지워라!

환경

E1: 여러 단계로 빌드해야 한다.

  • 한 명령으로 전체를 체크아웃 해서 한 명령으로 빌드할 수 있어야 한다.

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

  • 모든 단위 테스트는 한 명령으로 돌려야 한다.

함수

F1: 너무 많은 인수

  • 함수에서 인수 개수는 적을수록 좋다.
  • 아예 없으면 가장 좋다.

F2: 출력 인수

  • ❌ 출력 인수를 쓰지 말자.
  • 함수에서 뭔가의 상태를 변경해야 한다면, 함수가 속한 객체의 상태를 변경한다.

F3: 플래그 인수

  • ❌ 플래그 인수는 쓰지 말자.

F4: 죽은 함수

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

일반

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

  • 이상적으로는 소스 파일 하나에 언어 하나만 사용하는 방식이 가장 좋다.

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

  • 함수나 클래스는 다른 개발자가 당연하게 여길 만한 동작과 기능을 제공해야만 한다!

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

  • 코드는 올바르게 동작해야 한다.
    • 너무나도 당연한 말이다.
  • 모든 경계 조건을 찾아내고, 모든 경계 조건을 테스트하는 테스트 케이스를 작성하라!

G4: 안전 절차 무시

  • WARNING을 무시하지 마라.

G5: 중복

  • DRY
    • Don’t Repeat Yourself
  • 코드에서 중복을 발견할 때마다 추상화할 기회로 간주하라.

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

  • 추상화는 저차원 상세 개념에서 고차원 일반 개념을 분리한다.
  • 모든 저차원 개념은 파생 클래스에 넣고, 모든 고차원 개념은 기초 클래스에 넣는다.
  • ❌ 고차원 개념과 저차원 개념을 섞어서는 안 된다.
    • 세부 구현과 관련한 상수, 변수, 유틸리티 함수는 기초 클래스에 넣으면 안된다.

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

  • 고차워 기초 클래스 개념을 저차원 파생 클래스 개념으로부터 분리해 독립성을 보장하기 위해서다.
  • 일반적으로 기초 클래스는 파생 클래스를 아예 몰라야 마땅하다.

G8: 과도한 정보

  • 잘 정의된 인터페이스는 많은 함수를 제공하지 않는다.
    • 그래서 결합도(Coupling)이 낮다.
  • 클래스가 제공하는 메서드 수는 작을수록 좋다.
    • 변수 수도 작을수록 좋다.
    • 인스턴스 변수 수도 작을수록 좋다.

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: 정확하라

  • null 체크
  • 타입 정확성

G27: 관례보다 구조를 사용하라

G28: 조건을 캡슐화하라

  • 조건의도를 분명히 밝히는 함수로 표현하라!

G29: 부정 조건은 피하라

G30: 함수는 한 가지만 해야 한다.

G31: 숨겨진 시간적인 결합

  • 함수 인수나 수신 객체를 적절히 배치해 함수가 호출되는 순서를 명백히 드러내라!

G32: 일관성을 유지하라

G33: 경계 조건을 캡슐화 하라

  • 경계 조건은 변수로 캡슐화하는 편이 좋다.

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

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

G36: 추이적 탐색을 피하라

  • 디미터의 법칙

자바

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

  • 명시적인 import문은 강한 의존성을 생성하지만, 와일드칻드는 그렇지 않다.

J2: 상수는 상속하지 않는다.

  • 대신에 static import를 사용하라.

J3: 상수 vs Enum

  • Enum을 마음껏 활용하라!

이름

N1: 서술적인 이름을 사용하라

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

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

N4: 명확한 이름을 사용하라

N5: 코드가 길어진다면 긴 이름을 사용하라

N6: 인코딩을 피하라

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

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

테스트

T1: 불충분한 테스트

  • 테스트 케이스가 확인하지 않는 조건이나 검증하지 않는 계산이 있다면, 그 테스트는 불완전하다.

T2: 커버리지 도구를 사용하라!

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

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

T5: 경계 조건을 테스트하라!

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

T7: 실패 패턴을 살펴라

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

T9: 테스트는 빨라야 한다

profile
Hello velog!

0개의 댓글