[리팩토링] 악취 25 : 주석

 

✍️ 악취 25 : 주석

주석이 많다는 것은 코드에 악취가 많다는 방증이기도 하다. 주석이 많이 달린 코드를 리팩토링의 대상으로 선정해서 리팩토링을 적용한다면 코드가 가진 문제점을 해결하면서 동시에 주석이 필요 없어질 수도 혹은 주석의 내용이 간결하고 명확해질 수 있다.

 

주석이 많이 달린 코드 뭉치는 '함수 추출하기'를 사용해서 별도의 메서드로 분리할 수 있고, 장황하고 긴 이름의 메서드는 '함수 선언부 변경하기'를 적용할 수 있다. 주석에 명시된 시스템의 규약을 '어서션 추가하기'로 변경할 수도 있다.

 

여기 주석 악취를 해결하기 위한 세 가지 리팩토링 기법이 있다.

1. "함수 추출하기주석이 달린 코드 뭉치가 있다면

2. "함수 선언부 변경하기" 주석이 달린 장황하고 긴 이름을 가진 메서드가 있다면

3. "어서션 추가하기" 시스템의 규약을 코드로 표현하기

 

본 포스팅에서 관심 있게 살펴볼 리팩토링은 시스템의 규약을 주석이 아닌 코드로 표현하는 '어서션 추가하기'이다.

 

🍊 어서션 추가하기

코드로 표현하지는 않았지만 기본적으로 가정하고 있는 조건들이 있다. 그런 조건은 코드를 이해하거나 '주석'을 읽으면서도 확인할 수 있지만 Assertion을 보고 직관적으로 이해하는 방법도 있다.

 

Assertion은 if나 switch와 달리 '항상' true를 기대하는 조건을 표현할 때 사용된다. 개발 과정에서 Assertion에서 실패한다면 프로그래머의 실수로 판단해서 논리적인 오류에 대응하거나 방어 코드를 작성할 수 있다.

 

주석으로 작성된 규약을 Assertion으로 변경할 수 있다.

public class Customer {

    /**
     * discountRate은 0 보다 커야한다.
     */
    private double discountRate;

    public Customer(double discountRate) {
        this.discountRate = discountRate;
    }

    public double applyDiscount(double amount) {
        return amount - (this.discountRate * amount);
    }
}

 

Assertion 적용

* Assertion은 별도의 옵션이 없다면 런타임에 조건을 체크하지 않으며 오버헤드가 있기에 상용 코드에선 포함하지 않고 개발 코드에서만 사용하는 것을 권장한다. 따라서 개발 과정에서 Assertion으로 시스템의 홀을 발견했다면 Assertion을 제거하고 반드시 논리적 오류를 수정하거나 방어 코드로 변경해야 한다.

public class Customer {

    private double discountRate;

    public Customer(double discountRate) {
        assert discountRate > 0;

        this.discountRate = discountRate;
    }

    public double applyDiscount(double amount) {
        return amount - (this.discountRate * amount);
    }

}

// 방어 코드 추가
public Customer(double discountRate) {
    if(discountRate <= 0)
        throw new IllegalArgumentException();

    this.discountRate = discountRate;
}