Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

Optional 본문

Project/블로그 게시판 만들기

Optional

Seung__ 2021. 10. 16. 13:20

이전에는 Repository에서 모든 메서드를 Optional로 반환하였다.

 

따라서 Service에서는 Optional로 받고 null이 반환된 경우는 NoResultException을 던졌다.

 

앞서 테스트를 진행하면서 Optional을 너무 무지성으로 사용하는게 아닌가 라는 생각이 들었다.

 

Optional를 다시 한번 이해할 필요가 있다.

 

 

Java Optional 바르게 쓰기

Java Optional 바르게 쓰기Brian Goetz는 스택오버플로우에서 Optional을 만든 의도에 대해 다음과 같이 말했다. … it was not to be a general purpose Maybe type, as much as many people would have liked us to do so. Our intention w

homoefficio.github.io

(위의 글을 참고하여 주의사항만 발췌함)

 

1.Optional


  • A container object which may or may not contain a non-null value.
  • If a value is present, isPresent() returns true.
  • If no value is present, the object is considered empty and isPresent() returns false.
  • 한마디로 null일수도 non-null일수도 있는 객체를 포함하는 container다.

 

2. 주의사항


  • isPresent()-get() 대신 orElse()/orElseGet()/orElseThrow()
  • orElse(new ...) 대신 orElseGet(() -> new ...)
    • orelse(...)에서 ...는 항상 실행됨.
    • ...에서 새로운 객체생성이 필요하면 orElseGet()을 사용하자.
  •  단지 값을 얻을 목적이라면 Optional 대신 null 비교

  • Optional 대신 비어있는 컬렉션 반환
    • 컬렉션을 반환하는 Spring Data JPA Repository 메서드는 null을 반환하지 않고 비어있는 컬렉션을 반환
    • Optional로 감쌀 필요가 없음 ㅋㅋㅋ 

  • Optional을 필드로 사용 금지

  • Optional을 생성자나 메서드 인자로 사용 금지

  • Optional을 컬렉션의 원소로 사용 금지

  • of(), ofNullable() 혼동 주의

  • Optional<T> 대신 OptionalInt, OptionalLong, OptionalDouble

 

 

3. 코드 수정


  • 이전까지는 무지성으로 NoresultException을 반환했다.
  • 위의 내용을 보니 2가지가 현재 코드에 적용되어야 한다.
    • orElse(new ...) 대신 orElseGet(() -> new ...)
    • Optional 대신 비어있는 컬렉션 반환 ->이미 적용됨.
  • orELseGet()으로 변경해야 하는 이유는 다음과 같다.
    • 어쨌든 null을 반환하는 것 보다 빈 객체를 전달하고 싶다.
    • 빈 객체를 전달하면 Controller 계층에서 결과가 없는 경우를 처리하기가 더 쉽다.
    • 예외를 던져보니 처리하기가 쉽진 않았다..
  • 코드 변경
    • 다음과 같이 수정해주었다. 
    • 다른 Service에도 적용.
    @Override
    public Post findPostByTitle(String title) {
        return  postRepository.findByTitle(title).orElseGet(Post::new);
    }

    @Override
    public List<Post> findAll() {
        return postRepository.findAll();
    }
  • 각 domain 에 isEmpty()메서드를 추가해 줬다.
    public Boolean isEmpty(){

        if(this.getId() == null
            && this.getComments().size() == 0
            && this.getMember() == null
            && this.getTitle() == null) {

            return true;
        }
        return false;
    }

 

4. Test


  • 바로 테스트를 돌려보면 당연히 실패할것 ㅋㅋㅋㅋ

  • NoresultException을 받는 테스트가 실패했다.
  • Test를 다음과 같이 변경!
    @Test
    void findPostByIdNoResult2(){

        //given
        Long id = 321321L;

        //when
        Post postById = postService.findPostById(id);

        //then
        assertThat(postById.isEmpty()).isTrue();
    }

 

 

5. 결과


  • 모든 테스트 정상
  • url로 비 정상적인 조회 메서드 요청 시 처리 방법 필요.

 

 

6. GitHub: 211016 Optional


 

GitHub - bsh6463/blog

Contribute to bsh6463/blog development by creating an account on GitHub.

github.com

 

Comments