작성
·
195
·
수정됨
0
User가 UserLoanHistory를 가지게 됨으로써 대출하는 로직이 간단해지지만 UserLoanHistory관련 CRUD를 전부 User에서 비즈니스 로직을 처리해야하는 건가요? User가 처리하는 로직이 너무 많아지는 것 같아 이게 객체지향적인 게 맞나 고민이 되네요 현재 경우는 C U 밖에 없지만 만약 예를 들어서 작가와 책 엔티티가 있을 때 연관관계의 주인은 책에 있지만 작가가 보유한 책을 조회하는 로직을 더 간편하게 처리하기 위해 작가는 책을 리스트로 가지면서 생명주기를 관리하면, 책을 수정하거나 삭제할 때도 무조건 작가의 도메인에서 로직을 처리하게 되는 건가요? 단일책임원칙을 위배하는 것이 아닌가 고민이 되어 질문드립니다!
답변 1
1
안녕하세요! gang01님! 🙂 좋은 질문 감사드립니다.
하나씩 답변 드려볼게요! 👍
User가 UserLoanHistory를 가지게 됨으로써 대출하는 로직이 간단해지지만 UserLoanHistory관련 CRUD를 전부 User에서 비즈니스 로직을 처리해야하는 건가요?
제 생각에는 그렇지 않습니다! User
가 List<UserLoanHistory>
를 갖게 되면서 간단하게 구현할 수 있는 부분은 간단히 구현하는 것이고, 굳이 User
를 거쳐 UserLoanHistory
를 접근할 필요가 없다면 바로 UserLoanHistory
를 접근해도 된다고 생각합니다.
따라서 예시로 주신 경우에도, 각 기능에 더 맞는 좋은 방법을 선택하면 된다고 생각합니다! 꼭 1 : N 으로 연결이 되었다고 해서 N을 제어하려 할 때 1을 반드시 거칠 필요는 없어요!
예를 들어 작가 : 책 = 1 : N 으로 연결된 상황에서, "현재 우리 시스템에 등록된 책 권수"를 확인하는 기능을 만드려면 select count(1) from book
이라는 SQL을 바로 책 쪽에 적용함으로써 굳이 작가를 거치지 않고 기능을 구현할 수 있습니다. 😊
그렇다면 이런 궁금증이 생기실 수도 있습니다.
만약 1 : N 연관관계에서 N 쪽만 사용할 일이 많다면, 굳이 연관관계를 맺어야 할까? 🤔
저는 개인적으로 N 쪽만 사용할 일이 많다면, 특히 수정/삭제/생성이 1을 거치지 않고 N에서만 발생한다면, 연관관계를 맺지 않는 편입니다. 즉, 두 도메인의 Life Cycle이 상당 부분 일치해야 연관관계를 사용하는 것이죠!
이와 관해서는 아무래도 정답이 없다 보니, gang01님께서도 나름대로의 기준을 찾아보셔도 좋을 것 같습니다! 😊
추가로, 언급해주신 "단일 책임 원칙"에 대해서도 제 의견을 말씀드려보면, 어떤 객체가 "단일 책임 원칙"을 위배했는가? 위배 하지 않았는가? 는 객관적으로 판단하기 꽤 어렵다고 생각합니다. 결국 무엇까지를 "단일 책임"으로 볼 것인지 사람마다 의견이 다를 수 있기 때문이죠.
예를 들어, 우리가 만든 UserService
클래스도 단일 책임을
"유저와 관련된 비즈니스 로직을 처리하기 위한 트랜잭션, 도메인 제어와 관련된 책임" 이라고 생각하면 단일 책임 원칙을 지키고 있다고 생각할 수 있지만,
"유저를 생성도 하고, 수정도 하고, 삭제도 하고, 조회도 하네?" 라고 바라보면 무려 네 가지 책임을 갖고 있어 단일 책임 원칙을 지키지 못하고 있다고 생각할 수도 있습니다.
실제 이런 패턴을 사용한 방법도 있죠! 🙂 https://johngrib.github.io/wiki/article/hierarchical-controller-package-structure/
결론적으로, "이렇게 하면 된다"라는 100% 완벽한 정답이 없지만, 그렇기에 각자의 기준을 고민하고 서로 의견을 교환하는게 중요하지 않나 싶습니다! 😊
답변이 도움이 되었으면 좋겠습니다. 감사합니다. 🙇