ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • TIL 자바 스프링부트 서버개발 올인원 : 35강
    Java 2024. 5. 11. 00:01

    아래와 같은 형식으로 리팩토링 하기 위해서 OneToMany / ManyToOne / 연관관계의 주인을 알아봤다. 

    출처 : 인프런 -  자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]

    User도메인과 UserLoanHistory도메인이 직접적으로 연결되도록 리팩토링 해보자

     

    우선 User도메인에 userLoanHistorties에 cascade옵션과 orphanRemoval옵션을 설정해주고

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
    List<UserLoanHistory> userLoanHistories = new ArrayList<>();

     

    loanBook메서드를 만들어서 해당 메서드에서 userLoanHistories에 리스트를 추가할 수 있도록 해준다.

    public void loanBook(String bookName) {
        this.userLoanHistories.add(new UserLoanHistory(this, bookName));
    }

     

    BookService에서는 userLoanHistoriyRepository를 직접적으로 사용하지 않고 user객체를 통해서 loanBook 메서드를 호출한다. (주석부분은 리팩토링 전의 코드)

            // 5.유저 정보와 책 정보를 기반으로 UserLoanHistory 저장
    //      userLoanHistoryRepository.save(new UserLoanHistory(user, book.getName()));
            user.loanBook(book.getName());

    이렇게 리팩토링하게 되면 서비스단에서 userLoanHistory객체를 직접적으로 사용하지 않게 되고, User도메인에서 UserLoanHistory도메인을 처리하게 된다.

    이렇게 서비스단이 아닌 도메인끼리 직접적으로 협력하게 바뀐것을 가리켜 "도메인 계층에 비즈니스 로직이 들어갔다"라고 표현하기도 한다.

     


    도메인 계층에 비즈니스 로직이 들어갔다

    출처 : 인프런 -  자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]

    원래는 서비스단에서 여러 도메인을 가져와서 로직을 처리했었지만, JPA의 연관관계 옵션을 활용해서 최대한 도메인들 끼리 직접 협력할 수 있도록 한 것이다.

     


    영속성 컨텍스트의 지연로딩(Lazy Loading)

    출처 : 인프런 -  자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]

    user를 가져오는 부분과 도메인 로직 실행중간에 Hello 라는 출력을 하게 되면

    출처 : 인프런 -  자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]

    위와 같이 출력이 된다. 

    user를 가져오는 부분이 실행이 되고, Hello를 출력하고, 도메인 로직(userLoanHistory를 찾는 로직)을 실행하는 것이다.

    즉, 꼭 필요한 순간에 데이터를 로딩하는 지연로딩이 된다. 

     

    지연로딩은 OneToMany에 Fetch 옵션에서 설정할 수 있는데, 기본값이 Lazy이다. 해당 옵션을 Eager로 설정하면 필요한 순간에 User와 userLoanHistory를 가져오는게 아니라, 한번에 데이터를 가져오게 된다.

     

    지연로딩이 가능하기 위해서는 영속성 컨텍스트가 있어야만(트랜잭션 내 환경에서만) 가능하다.


    연관관계 사용의 장점과 단점

    객체 지향적으로 코딩을 하기 위해서 service에서 여러 도메인을 가져다가 사용하는 것이 아닌, 도메인끼리 협업하도록 했고 그 과정에서 JPA 연관관계를 사용했다. 

     

    이렇게 연관관계를 사용했을 때 장점은 무엇인가?

     

    1. 각자의 역할에 집중하게 된다(계층 별로 응집성이 강해진다).

    서비스 계층의 역할은 꼭 필요한 경우에 서로 다른 도메인이 협업할 수 있도록 도와주고 트랜잭션을 관리하고, 외부 의존성을 관리하는 역할이다. 도메인은 도메인 객체가 표현하는 비즈니스를 처리하는 것으로 이를 더 잘 표현할 수 있게 된다.

     

    2. 새로운 개발자가 코드를 읽을 때 이해하기 쉬워진다.

    서비스에 모든 비즈니스 로직이 있을 경우, 절차지향적이고 길기 때문에 로직을 이해하기 힘들어진다. 하지만 연관관계를 사용해서 객체지향적으로  코딩을 하게되면 각 도메인별로 어떤 일을 하는지 파악할 수 있기 때문에 이해하기  쉬워진다.

     

    3. 테스트 코드 작성이 쉬워진다.

    비즈니스 로직이 부분별로 나눠지게 되기 떄문에 테스트 코드 작성이 쉬워진다.

     

    그러나 연관관계를 사용하는 것이 항상 좋지는 않다.

     

    연관관계를 사용하는 것은 객체들끼리 얽히고 설키게 되는 것이다. 그렇기에 지나치게 사용하게 되면 성능상의 문제가 생길 수 있고 도메인간의 복잡한 연결로 인해 시스템을 파악하기 어려워질 수 있다.

    또한 너무 얽혀 있으면 A를 수정했을 때 B C D까지 영향을 주게 된다.

     

    비즈니스 요구사항, 기술적인 요구사항, 도메인 아키텍쳐 등 여러 부분을 고민해서 연관관계를 사용해야한다. 

Designed by Tistory.