Java

Enum으로 분기문 다루어보기

다음과 같은 요구사항이 있다.

 

로그인 사용자의 경우 연령별 요금으로 계산

  • 청소년: 운임에서 350원을 공제한 금액의 20%할인
  • 어린이: 운임에서 350원을 공제한 금액의 50%할인

- 청소년: 13세 이상~19세 미만

- 어린이: 6세 이상~ 13세 미만

 

이 또한 if-else를 통해 사용자가 청소년인지, 어린이인지, 혹은 그에 해당하지 않는 지 확인한 뒤 그에 알맞은 요금을 계산해서 리턴할 수 있다.

하지만, 이번에는 Enum을 이용해 처리해보자.

 

사실 Enum을 사용하는 이유는 Enum의 필드로서 함수형 인터페이스를 받은 뒤, 그에 알맞은 Enum Type을 갖도록 함으로서 분기문을 다룰 수 있기 때문이다.

 

먼저 코드로 보자면 다음과 같다.

public enum AgePolicy {
    TWENTIES(age -> age > 19, 0, 0),
    TEENAGERS(age -> 13 <= age && age < 19, 350, 0.2),
    PRESCHOOLER(age -> 6 <= age && age < 13, 350, 0.5),
    BABIES(age -> age < 6, 0, 1);

    private final IntPredicate agePredicate;
    private final int deductionFare;
    private final double discountRate;

    AgePolicy(IntPredicate agePredicate, int deductionFare, double discountRate) {
        this.agePredicate = agePredicate;
        this.deductionFare = deductionFare;
        this.discountRate = discountRate;
    }

    public static AgePolicy of(int age) {
        return Arrays.stream(AgePolicy.values())
                .filter(agePolicy -> agePolicy.agePredicate.test(age))
                .findAny()
                .orElseThrow(() -> new IllegalArgumentException("해당하는 나이가 존재하지 않습니다."));
    }

    public int calculateFareAppliedAgePolicy(int currentFare) {
        return (int) ((currentFare - deductionFare) * (1 - discountRate));
    }
}

 

분기문을 통해 이 사용자가 청소년인지, 어린이인지 구분할 것을 Enum의 values를 활용하여 모든 enum을 돌면서 첫번째 인자인 Inpredicate에 알맞은 age인지 확인하고, 그에 알맞은 Enum 객체를 리턴한다.

 

사실, 이 방법이 분기문을 개선했는지에 대해서는 잘 모르겠다.

단순히 두 개의 for-loop를 stream을 이용해 한줄로 작성하듯이, 이 또한 반복되는 if-else문을 함수형 인터페이스를 이용해 줄였지 "개선"은 아닌 것 같다는 생각이 들기도 한다.

 

아무튼 위와 같은 방식으로 if-else를 클래스 내부에서 처리할 수 있다.

 

(이 내용은 함수형 인터페이스에 대해 공부한 뒤 조금 더 보완하겠다.)