[클린코드] 17장. 냄새와 휴리스틱

June·2021년 12월 23일
0

[클린코드]

목록 보기
14/15

주석

주석은 빨리 낡는다. 쓸모 없어질 주석은 아예 달지 않는 편이 가장 좋다. 쓸모 없어진 주석은 빨리 삭제하자.

환경

빌드는 간단히 한 단계로 끝나야 한다.

아무리 열악한 환경이라도 셸에서 명령 하나로 테스트가 가능해야 한다.

중복

코드에서 중복을 발견할 때마다 추상화할 기회로 간주하라. 중복된 코드를 하위 루틴이나 다른 클래스로 분리하라. 이렇듯 추상화로 중복을 정리하면 설계 언어의 어휘가 늘어난다. 중복한 함수/다형성/디자인 패턴 등으로 제거할 수 있다.

추상화 수준

추상화는 저차원 상세 개념에서 고차원 일반 개념을 분리한다. 세부 구현과 관련한 상수, 변수, 유틸리티 함수는 기초 클래스에 넣으면 안된다. 기초 클래스는 구현 정보에 무지해야 마땅하다.

기초 클래스는 파생 클래스를 아예 몰라야 마땅하다.

잘 정의된 모듈은 인터페이스가 아주 작다. 클래스가 제공하는 메서드 수는 작을 수록 좋다. 함수가 아는 변수 수도 작을수록 좋다. 클래스에 들어있는 인스턴스 변수 수도 작을수록 좋다.

인위적 결합

서로 무관한 개념을 인위적으로 결합하지 않는다. 예를 들어, 일반적인 enum은 특정 클래스에 속할 이유가 없다. enum이 클래스에 속한다면 enum을 사용하는 코드가 특정 클래스를 알아야만 한다. 범용 static 함수도 마찬가지로 특정 클래스에 속할 이유가 없다.

부적절한 static 함수

함수를 재정의할 가능성이 존재한다면 static보다 인스턴스 함수가 더 좋다.

함수는 한 가지만 해야 한다

public void pay() {
    for (Employee e: employees) {
        if (e.isPayDay()) {
           Money pay = e.calculatepay();
           e.deliveryPay();
         }
     }
 }

위 코드는 세 가지 임무를 수행한다. 직원 목록을 루프로 돌며, 각 직원의 월급일을 확인하고, 해당 직원에게 월급을 지급한다. 위 함수는 다음 함수 셋으로 나누는 편이 좋다.

public void pay() {
   for (Employee e: employees) {
       payIfNecessary(E);
    }
}

private void payIfNecessary(Employee e) {
    if (e.isPayDay())
        calculateAndDeliveryPay(e);
}

private void calculateAndDelivery(Employee e) {
    Money pay = e.calculatePay();
    e.deliveryPay();
}

추이적 탐색을 피하라

일반적으로 한 모듈은 주변 모듈을 모를수록 좋다. A가 B를 사용하고, B가 C를 사용하더라도 A가 C를 알아야 할 필요는 없다는 뜻이다. 예를 들어 a.getB().getC().doSomething()은 바람직하지 않다. 이를 디미터의 법칙이라 부른다.

여러 모듈에서 a.getB().getC()라는 형태를 사용하면 B와 C 사이에 Q를 넣기가 쉽지 않다. 그래서 아키텍처가 굳어진다.

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

구현을 드러내는 이름은 피하라. 작업 대상 클래스나 함수가 위치하는 추상화 수준을 반영하는 이름을 서택해라.

0개의 댓글