Optional에 대한 기본적인 정의나 상세한 설명은 다른 블로그에도 설명이 잘 되어있습니다.
Optional에 대해 기본적인 숙지를 하시고 보시길 추천드립니다.
블랙잭 미션에서는 로또미션과 다르게 Enum에 쓸모 없는 인스턴스를 두지 않았습니다.
그래서 반환타입에 처음으로 Optional을 사용했는데
- get()을 사용해야할 지
- orElse()를 사용해야할 지
- orElseThrow()를 사용해야할 지
- Optional로 반환해 클라이언트에게 책임을 넘기고, 클라이언트는 어떻게 사용해야할 지
앞으로 사용할 방법을 정형화 하기 위해 포스팅을 했습니다.
로또미션
OTHER (나머지) 라는 인스턴스가 존재합니다.
public enum Rank {
OTHER(0,false, 0),
FIFTH(3, false, 5_000),
FOURTH(4, false, 50_000),
THIRD(5, false, 1_500_000),
SECOND(5, true, 30_000_000),
FIRST(6, false, 2_000_000_000);
그래서 인자를 받고 해당하는 인스턴스를 넘겨주는 static 메서드를 작성할때 아래와 같이 Optional을 사용하지 않고도 작성이 가능합니다.
public static Rank value(int count, boolean bonus) {
for (Rank rank : Rank.values()) {
if (rank.count == count && rank.bonus == bonus) {
return rank;
}
}
return OTHER;
}
반면에,
블랙잭미션은
승, 패, 무 외에 Other 인스턴스 없이 구성했습니다.
public enum Match {
WIN(1, "승"),
LOSE(-1, "패"),
DRAW(0, "무")
;
로또 미션때 처럼 인자로 받는 값에 해당하는 반환값을 구성할때 null을 반환하지 않도록 Optional을 사용하기로 결정했습니다.
Optional을 사용할때 자주 사용되는 반환은 아래 4가지로 구성됩니다.
- get() 사용하기
- orElse()를 사용하기
- orElseThrow()를 사용하기
- Optional로 반환해 클라이언트에게 책임을 넘기고, 클라이언트에서 IfPresent()를 사용하기
get()
public static Match of(int number) {
return Arrays.stream(values())
.filter(it -> it.value == number)
.findFirst()
.get();
}
get()을 사용하면 값이 있을 경우 값을 반환하고, 없을 경우 NoSuchElementException을 반환합니다.
장점
- 작성하기 편하다
단점
- NoSuchElementException을 반환할 가능성이 있다.
- 어딘가에서 예외처리를 해주어야 한다.
get()은 IfPresent로 값 체크 없이 사용하면 안됩니다.
orElse()
public static Match of(int number) {
return Arrays.stream(values())
.filter(it -> it.value == number)
.findFirst()
.orElse(WIN);
}
값이 없을 경우 매개변수로 지정해준 값을 반환한다.
장점
- 예외가 발생하지 않는다.
단점
- 넣어줄 값이 없을 땐 사용하기 애매하다.
orElseThrow
public static Match of(int number) {
return Arrays.stream(values())
.filter(it -> it.value == number)
.findFirst()
.orElseThrow(IllegalArgumentException::new);
}
값이 있을 경우 값을 반환하고, 없을 경우 지정해준 예외(IllegalArgumentException)를 반환합니다.
장점
- 작성하기 편하다
- 인자로 어떤 값을 넣어주지 않아도 된다.
단점
- 예외를 반환할 가능성이 있다.
- 어딘가에서 예외처리를 해주어야 한다.
후니나 리뷰어분이 이 방법을 추천했는데, 예외를 어디서 처리해줄 지 애매해서 블랙잭에선 사용하지 않았습니다.
추후에 orElseThrow() 사용과 관련된 정보를 추가로 포스팅할 예정입니다.
Optional 반환
public static Optional<Match> of(int number) {
return Arrays.stream(values())
.filter(it -> it.value == number)
.findFirst();
}
장점
- 작성하기 편하다
- 예외도 반환하지 않는다.
단점
- 사용하는 쪽에서 검증코드가 필요하다.
검증코드 예시
아래의 검증코드에선 ifPresent로 Optional 안에 값이 있을 경우에만 코드를 실행하도록 두었습니다.
만약 Optional에 값이 없을 경우에는 아무수행도 하지 않도록 두었습니다.
Optional<Match> matchResult = Match.of(player.compareCardsSumTo(sum));
matchResult.ifPresent(match -> result.put(player.getName(), match));
결론
프로젝트가 해당 메서드에서 반환된 예외를 처리할 수 있는 구조라면 orElseThrow를 사용해 원하는 예외를 반환한다.
그게 아니라면 Optional을 반환후 ifPresent를 통해 값이 있는 경우와 없는 경우를 따로 처리해주는 코드를 짠다.
'Web > Java' 카테고리의 다른 글
[Java] for-loop 와 stream.forEach() 는 다르다. (6) | 2022.03.04 |
---|---|
[Java] java.lang.String의 isEmpty() vs isBlank() (3) | 2022.02.18 |
[우테코 프리코스] 최종시험 + 최종합격 (3) | 2021.12.31 |
[우테코 프리코스] 3주차: 자판기 (2) | 2021.12.11 |
[우테코 프리코스] 2주차: 자동차 경주 게임 (0) | 2021.12.01 |