책 내용 정리/[책] 내 코드가 그렇게 이상한가요?

12장 메서드: 좋은 클래스에는 좋은 메서드가 있다.

문자메일 2023. 7. 28. 04:45

12.1 반드시 현재 클래스의 인스턴스 변수 사용하기

메서드는 반드시 현재 클래스의 인스턴스 변수를 사용하도록 설계하는 것이 기본 원칙이다.

다른 클래스의 인스턴스 변수를 변경하는 메서드는 좋지 않다. (응집도가 낮은 구조가 될 수 있끼 때문이다.)

 

12.2 불변을 활용해서 예상할 수 있는 메서드 만들기

 

12.3 묻지 말고 명령하라

 

12.4 커맨드/쿼리 분리

아래 메서드는 상태 변경과 추출을 동시에 하고 있다.

int gainAndGetPoint(){

    point += 10;

    return point;

}

 

상태 변경과 추출을 동시에 하는 메서드는 여러 문제의 원인이 된다고 한다.

커맨드-쿼리 분리라는 패턴이 있다. 메서드는 커맨드 또는 쿼리 중에 하나만 하도록 설계해야 한다는 패턴이다.

메서드 종류 구분 설명
커맨드 상태를 변경하는 것
쿼리 상태를 리턴하는 것
모디파이어 커맨드와 쿼리를 동시에 하는 것

// 포인트를 증가(커맨드)

void gainPoint(){

    point += 10;

}

 

// 포인트를 리턴(쿼리)

int getPoint(){

    return point;

}

 

 

12.5 매개변수

 

12.5.1 불변 매개변수로 만들기

매개변수를 변경하면 값의 의미가 바뀌어서, 어떤 의미를 나타내는지 유추하기 힘들다.

 

12.5.2 플래그 매개변수 사용하지 않기

 

12.5.3 null 전달하지 않기

null을 활용하는 로직은 NPE가 발생할 수 있으며, null을 확인해야 하므로 로직이 복잡해지는 등 다양한 문제를 일으킨다.

null을 전달하지 않게 설계하려면, null에 의미를 부여해서는 안 된다.

이전 다른 예시에서 장비를 착용하지 않은 상태를 null로 나타내지 않고 Equipment.EMPTY로 표현했던 것 처럼 구현할 것

 

12.5.4 출력 매개변수 사용하지 않기

매개변수는 입력 값으로 사용하는 것이 기본이다.

매개변수를 출력 값으로 사용하면, 코드를 읽는 사람에게 혼란을 줄 수 있다. (경험해봐서 알지..)

가독성 저하의 원인이 되므로, 출력 매개변수는 사용하지 않는 것이 좋다.

 

12.5.5 매개변수는 최대한 적게 사용하기

매개변수는 최대한 적게 설계하는 것이 좋다.

매개변수가 많아질 수 밖에 없다면, 별도의 매개변수 모음 클래스로 만드는 방법 검토해 보는 것이 좋다.

 

 

12.6 리턴 값

 

12.6.1 자료형을 사용해서 리턴 값의 의도 나타내기

 

기본 자료형은 의도가 불분명함,

아래처럼 int 자료형처럼 단순한 기본 자료형으로는 리턴한 값의 의미를 호출하는 쪽에 전달할 수 없다.

class Price{

    // 생략

    int add(final Price other){

        return amount + other.amount;

    }

}

 

int price = productPrice.add(otherPrice); // 상품 가격 합계

int discountedPrice = calDiscountedPrice(price); // 할인 금액

int deliveryPrice = calcDeliveryPrice(discountedPrice); // 배송비

 

금액을 계산할 때는 위 처럼 다양한 종류의 가격을 함께 다루는 경우가 많은데, int 자료형을 리턴하게 만들면 어떤 값이

어떤 금액을 의미하는지 알기 힘들고, 아래처럼 메서드에 매개변수를 잘못 전달하는 실수가 발생할 수 있다.

DeliveryCharge deliveryCharge = new DeliveryCharge(price);

 

따라서 기본 자료형을 사용하지 말고, 독자적인 자료형을 사용해서 의도를 명확하게 나타내는 것이 좋다.

class Price{

    Price add(final Price other){

        final int added = amount + other.amount;

        return new Price(added);

    }

}

 

아래 코드처럼 다른 금액 계산에서도 독자적인 자료형을 사용하면, 의도를 명확하게 나타낼 수 있고, 메서드 파라메터에 값을 실수로 잘못 넣어도 컴파일 오류 발생하며 막을 수 있다.

Price price = productPrice.add(otherPrice); // 상품 가격 합계

DiscountedPrice discountedPrice = calDiscountedPrice(price); // 할인 금액

DeliveryPrice deliveryPrice = calcDeliveryPrice(discountedPrice); // 배송비

 

12.6.2 null 리턴하지 않기

null을 return 하지 않는 것이 좋다.

 

12.6.3 오류 발생 시 오류 값 return하지 말고 exception 발생시키기!