본문으로 건너뛰기

Optional 실무적용

익숙하지는 않지만 옵셔널을 실무에 적용해서 사용해 보았다..

Price price = priceDao.selectPrice(paramsDto);

BigDecimal costA = new BigDecimal(BigInteger.ZERO);
BigDecimal costB = new BigDecimal(BigInteger.ZERO);

if (price != null) {
// A의 계산 가격
costA = price.getACost().multiply(usage);
// B의 계산 가격
costB = price.getBCost().multiply(usage);
}

이렇게 price라는 가격정보를 먼저 가져오고 가격이 없을경우엔 0.00 처리를 위해서 미리 기본값을 잡아놓고,
가격정보가 있을때에는 계산된 값을 집어 넣도록 했다.

나쁘다고 좋다고도 할 수 없다. 왜냐? 내가 볼때 이게 더 직관적으로 알아보기 쉬워서..

하지만 옵셔널을 한번 써보고 싶어 적용해 보았다.

Optional<Price> price = priceDao.selectPrice(paramsDto);

BigDecimal costA = price.map(priceData -> priceData.getACost().multiply(usage))
.orElseGet(() -> new BigDecimal(BigInteger.ZERO));
BigDecimal costB = price.map(priceData -> priceData.getBCost().multiply(usage))
.orElseGet(() -> new BigDecimal(BigInteger.ZERO));

요런 느낌으로 되었다. null체크없이 바로 계산된 것을 map을 이용해서 반환하는데 만약 null일경우에는 orElseGet으로 0.00을 넣어주는 것이다.
참고로 가격정보를 db에서 전부 삭제하고 실행 해본 것이다.

근데.. Optional을 쓴다고해서 null에 안전한것은 아니다.
밑에와 같이 해보니 바로 익셉션이 발생한다. -_-;;;;

System.out.println(price.get().getACost());

그러하다..

참고 : Optional이 감싸고 있는 값을 반환하고, 값이 없으면 NoSuchElementException 발생

참고 : 또한 get과 orElseThrow를 이용해서 Optional의 값을 얻을 수 있습니다.
하지만 이런 방식은 기존의 null을 체크하는 방식과 다른게 없거니와 오히려 Optional을 써서 타이핑만 더 치는 안 좋은 방법이라고 생각합니다.
하루 빨리 deprecated 됬으면 하는 개인적인 소망입니다.


옵셔널에 아직 많이 익숙하지는 않다... 스트림은 잘만 쓰는데.. 옵셔널만 보면 주눅이 드네...

하지만 조금씩 적용하다보면 익숙해질 것 같다.

다만,
옵셔널을 안쓰는 것이 더욱 직관적으로 알아보기 쉬운 코드라면, 전통적인 방식으로 옵셔널 없이 써내려가는것이 더 좋을것도 같다.