로또 미션 도중 순위를 Enum class로 표현하는 중 문제가 발생했다.
public enum Rank {
NOTHING(0, 0, false),
FIFTH(5_000, 3, false),
FOURTH(50_000, 4, false),
THIRD(150_000, 5, false),
SECOND(30_000_000, 5, true),
FIRST(2_000_000_000, 6, false);
private final int money;
private final int matchCounts;
private final boolean isBonus;
Rank(int money, int matchCounts, boolean isBonus) {
this.money = money;
this.matchCounts = matchCounts;
this.isBonus = isBonus;
}
}
위와 같은 코드로 순위를 표현했는데 isBonus라는 인스턴스 필드 값이 제 역할을 못하는 느낌을 받았다.
그 이유는, NOTHING, FIFTH, FOURTH, THIRD의 경우 보너스 번호의 일치 여부가 전혀 상관 없기 때문이다.
즉, isBonus 값이 true여도 되고 false여도 된다.
어떻게 해야 이 부분을 해결할 수 있을까 고민하다 다음과 같이 함수형 인터페이스를 사용했다.
public enum Rank {
NOTHING(0, 0, (matchCounts, bonus) -> matchCounts >= 0 && matchCounts < 3),
FIFTH(5_000, 3, (matchCounts, bonus) -> matchCounts == 3),
FOURTH(50_000, 4, (matchCounts, bonus) -> matchCounts == 4),
THIRD(150_000, 5, (matchCounts, bonus) -> matchCounts == 5 && !bonus),
SECOND(30_000_000, 5, (matchCounts, bonus) -> matchCounts == 5 && bonus),
FIRST(2_000_000_000, 6, (matchCounts, bonus) -> matchCounts == 6 && !bonus);
private final int money;
private final int matchCounts;
private final BiPredicate<Integer, Boolean> rankPredicate;
Rank(int money, int matchCounts, BiPredicate<Integer, Boolean> rankPredicate) {
this.money = money;
this.matchCounts = matchCounts;
this.rankPredicate = rankPredicate;
}
}
BiPredicate이라는 인터페이스를 사용해 인스턴스 필드로 matchCounts와 bonus 값을 이용한 메서드를 사용할 수 있었다.
이전과 비교했을 때, 함수형 인터페이스를 사용해 훨씬 명쾌하게 조건을 나타낼 수 있어졌다.
함수형 인터페이스(Fucntional Interface)란 ?
단 하나의 추상메서드를 가지는 인터페이스
위에서 사용한 BiPredicate는 다음과 같이 선언되어있다.
@FunctionalInterface
public interface BiPredicate<T, U> {
boolean test(T t, U u);
}
@FunctionalInterface라는 어노테이션의 의미는 이미 정의한 메서드 외에 부적절한 메서드를 추가하거나(static method, default method 제외) 다른 인터페이스를 상속받으면 에러가 발생한다. 즉, 주요한 한 개의 메서드만 정의할 수 있도록 강제하는 장치라고 할 수 있을 것 같다.
그렇다면 함수형 인터페이스는 왜 사용하는 것일까?
공부한 결과 함수형 인터페이스를 사용해서 얻을 수 있는 큰 장점은 기본형 데이터 뿐만 아니라 행위(로직)도 값으로 취급할 수 있게 된다는 점이다. 자바가 코드의 재활용 단위가 클래스 였던 것이 함수 단위로 재사용 가능해 지면서 조금 더 개발을 유연하게 할 수 있게 된 것이다.
'우아한테크코스 > prolog' 카테고리의 다른 글
스프링은 왜 쓸까? (feat. 끝장토론) (0) | 2022.05.09 |
---|---|
Servlet이란? (2) | 2022.04.29 |
래퍼 클래스와 오토 박싱 & 언박싱 (1) | 2022.02.18 |