강의

멘토링

로드맵

Inflearn brand logo image

인프런 커뮤니티 질문&답변

양용찬님의 프로필 이미지
양용찬

작성한 질문수

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

31강. 대출 기능 개발하기

user-loanHistory 폴더 구조 질문

작성

·

31

1

안녕하세요!
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true) private List<UserLoanHistory> userLoanHistories = new ArrayList<>(); 이 코드를 봤을 때 User와 UserLoanHistory는 강한 연결관계를 가지고 있는 것 같습니다(이를 같은 aggregate라고 하는 것 맞나요?). 그래서 폴더 구조를 user 밑에 loanHistory를 넣으신 것 같은데, 일반적으로 이런식으로 폴더 구조를 잡나요? 아니면 domain 폴더 아래에 user와 같은 레벨로 loanHistory를 만들고, 대출 기능도 BookService에서 구현하는 게 아니라 UserLoanHistory용 컨트롤러/서비스/레포지토리를 따로 만들어 구현해도 되나요?

답변 2

0

최태현님의 프로필 이미지
최태현
지식공유자

안녕하세요 용찬님! 🙂 정말 좋은 질문 감사드립니다.

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

우선 위 코드가 User와 UserLoanHistory의 '강결합'을 의미하는 것이 맞습니다.

또한, 이렇게 1) 강결합 되어 있으면서 2) 전체적인 비즈니스 맥락을 같이하는 객체들을 DDD에서는 Aggregate 라고 부루는 것도 맞습니다. (정확한 정의와 의미는 사람마다 조금 다를 수 있을 것 같아요!)

 

다음 질문으로 넘어가...

그래서 폴더 구조를 user 밑에 loanHistory를 넣으신 것 같은데, 일반적으로 이런식으로 폴더 구조를 잡나요?

하나의 Aggregate 안의 구성 요소가 여러개인 경우, 저는Aggregateroot (한 애그리거트의 가장 대표가 되는 객체, 여기서는 user가 됩니다) 패키지 아래 추가적인 패키지를 두는 방법을 제일 선호합니다. 🙂

다만 구성요소가 적다면 한 패키지 안에 넣는 경우도 있고, 드물긴 하지만 아예 다른 패키지에 위치시키는 경우도 있습니다. (ex. user 와 같은 레벨로 loanHistory 를 만드는 경우)

 

대출 기능도 BookService에서 구현하는 게 아니라 UserLoanHistory용 컨트롤러/서비스/레포지토리를 따로 만들어 구현해도 되나요?

넵! 🙂 충분히 어색하지 않을 것 같아요! "책"이라는 관점에서 보면 내가 대출 당하는 것이니 대출 관련 로직이 BookController, BookService 에 위치할 수 있겠지만 "유저" 관점에서 보면 내가 대출을 하는 것이니 유저 대출 관련 Controller, Service가 있어도 충분할 것 같습니다.

 

결국 어떤 코드를 어디에 위치시킬 것인지, 어떤 클래스를 어떤 패키지에 위치시킬 것인지는 정답이 잘 없는 것 같아요! 한 프로젝트 내에서 함께 하는 분들의 동의를 받을 수 있고, 일관성과 타당한 이유가 있다면 어떤 형태든지 충분히 괜찮은 것 같습니다. 🙏

 

답변이 도움이 되었으면 좋겠습니다. 감사합니다. 🙇

 

0

안녕하세요, 인프런 AI 인턴입니다. 양용찬님!

User와 UserLoanHistory 간의 강한 연결관계를 질문해 주셨네요. 말씀하신 대로 두 엔티티는 같은 Aggregate에 속한다고 볼 수 있으며, 이를 기반으로 폴더 구조를 잡는 방식에 대한 고민을 하고 계신 것 같습니다.

일반적으로, 폴더 구조를 잡을 때는 도메인과 관련된 엔티티들을 한 곳에 모아두는 방식을 주로 사용합니다. 따라서 User와 연관된 LoanHistory를 User 도메인 아래에 두는 것은 자연스러운 구조일 수 있습니다. 이는 User와 LoanHistory가 같은 비즈니스 로직에 밀접하게 연관되어 있고, 동일한 Aggregate로 관리하는 것이 이상적인 경우입니다.

그러나 프로젝트의 규모나 복잡성에 따라 여러 가지 구조가 존재할 수 있습니다:
1. Domain-Centric 구조: User와 UserLoanHistory를 같은 도메인(예: user) 아래에 배치하고, 관련 비즈니스 로직을 그 도메인 내의 서비스 클래스에 구현합니다.
2. 기능별 구성: 각각의 기능(예: 대출 기능, 반환 기능 등)에 맞춰 별도의 컨트롤러/서비스/레포지토리를 구성할 수도 있습니다.

(관련 게시물: User와 loanhistory 관계)

이와 관련하여 유사한 질문이 있어 아래 링크로 연결해 드리니 참고하시면 좋을 것 같습니다:
- User와 loanhistory 관계 - 연관관계와 책임 분리
- BookLoanRequest 위치에 대한 고민

위 질문에서는 User 도메인이 UserLoanHistory와 어떻게 구조적으로 연관될 수 있는지에 대한 설명이 포함되어 있으며, 더 나아가 기능적인 측면에서 어떻게 구성할 수 있을지에 대한 고민도 같이 나누고 있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

양용찬님의 프로필 이미지
양용찬

작성한 질문수

질문하기