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

junjun님의 프로필 이미지
junjun

작성한 질문수

Practical Testing: 실용적인 테스트 가이드

Business Layer 테스트 (2)

Order.class 에대하여

작성

·

230

0

  • 학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요!

  • 먼저 유사한 질문이 있었는지 검색해 보세요.

  • 서로 예의를 지키며 존중하는 문화를 만들어가요.

     

 

강의 듣다가 궁금한 점이 생겨서 질문을 작성합니다!

  1. Order 클래스는 @Entity 어노테이션이 붙어있는 도메인 객체인데 여기에 어떤 로직? 이라고 해야 하나요? List<OrderProduct> 를 바로 넣어주는 것이 아니고 List<Product>를 받아서 값을 뽑아서 new OrderProduct 로 생성하거나, calculateTotalPrice() 같은 메서드를 작성해도 괜찮은가요? (현업에서도 많이 쓰이는 방법인가요? 뭔가 따로 service로 빼도 괜찮지 않을까 라는 생각이 들었습니다. )

  2. 전에 간단한 토이 프로젝트를 할 때 cascade = CascadeType.ALL 가 아닌 cascade = CascadeType.REMOVE 로 설정하고 Order을 생성한 후 OrderProduct를 수동으로 생성했었는데 CascadeType.ALL 이 더 범용적으로 많이 쓰는 방법인지

테스트 코드 작성법을 배우려고 듣게 되었는데 뭔가 라이브 코딩을 따라가면서 전반적으로? 많이 배우고 있어서 좋아요! ㅎㅎ 좋은 강의 감사합니다.

답변 2

0

박우빈님의 프로필 이미지
박우빈
지식공유자

안녕하세요, junjun 님!

하나씩 답변 드리겠습니다.

 

1. Order 클래스는 @Entity 어노테이션이 붙어있는 도메인 객체인데 여기에 어떤 로직? 이라고 해야 하나요? List<OrderProduct> 를 바로 넣어주는 것이 아니고 List<Product>를 받아서 값을 뽑아서 new OrderProduct 로 생성하거나, calculateTotalPrice() 같은 메서드를 작성해도 괜찮은가요? (현업에서도 많이 쓰이는 방법인가요? 뭔가 따로 service로 빼도 괜찮지 않을까 라는 생각이 들었습니다. )

OrderProduct는 사실 Order와 Product의 다대다 관계로 인해 만들어진 중간 테이블 엔티티입니다.
외부에서는 Product를 가지고 Order를 만들려고 하는데, 굳이 OrderProduct라는 객체(관계)를 알 필요가 없습니다.

말씀하신 가공 로직이나, calculateTotalPrice() 같이 도메인 내부에서 가지고 있는 정보들을 이용하여 도메인 fit하게 제공하는 로직을 '도메인 로직'이라고 한다면,
도메인 객체가 마땅히 가져야 할 도메인 로직이 외부로 분리되어 있는 것이 더 어색하지 않을까요? ㅎㅎ

위와 같은 로직이 Service로 분리된다면, 응집도가 낮아지는 것을 경험하게 됩니다.
Service에서는 데이터 가공을 위해 Order가 캡슐화한 많은 정보들이 필요할텐데, 그때마다 getter로 데이터를 취득해서 가공을 하게 되겠죠.
결과적으로 복잡한 로직이 늘어나고, 필요없는 getter가 더 생긴다던가 하는 불필요한 행위가 생길 수 있습니다.
하나여야 마땅한 개념이 두 군데로 나뉘어졌기 때문이죠.

물론 Order가 워낙 중요한 객체고, 프로젝트가 발전함에 따라 가지고 있는 책임이 점점 많아져서 관리가 힘들어진다면, 그 때에는 말씀하신 것처럼 세부적인 책임에 따라 객체를 분리하는 시도를 해볼 수 있습니다. ㅎㅎ
다만, 그때에도 도메인 객체가 여러 책임에 따라 조금 더 세분화되는 것이지, 도메인 객체가 그에 맞는 도메인 로직을 가져야 한다는 방침에는 변함이 없습니다.

 

2. 전에 간단한 토이 프로젝트를 할 때 cascade = CascadeType.ALL 가 아닌 cascade = CascadeType.REMOVE 로 설정하고 Order을 생성한 후 OrderProduct를 수동으로 생성했었는데 CascadeType.ALL 이 더 범용적으로 많이 쓰는 방법인지

말씀하신대로 설계 의도에 따라 필요한 만큼의 범위만 cascade 설정을 거는 것이 권장하는 방식이긴 합니다.
보통 저 같은 경우 실무에서는 cascade 설정을 사용한다는 것 자체가 두 엔티티가 긴밀한 관계인 경우가 많아서, 매번 하나씩 따지기 보다는 편하게 ALL로 적용하고 관련 CRUD 상황에서 주의해서 관리하는 편입니다.
정답이 있는 것은 아닙니다. ㅎㅎ

 

감사합니다. 🙂

junjun님의 프로필 이미지
junjun
질문자

자세한 설명 감사합니다!!

0

안녕하세요, 인프런 AI 인턴입니다.

junjun님, 질문하신 내용과 관련하여 유사한 상황에 대한 답변 링크를 찾았습니다. 아래의 링크를 참조하시면 도움이 될 것 같습니다.

  1. OrderProduct 클래스 질문: 이 링크에서는 OrderProduct 클래스와 관련된 @ManyToOne@OneToMany 어노테이션 사용에 대한 지식공유자의 설명이 있습니다. Order 클래스 내에서 로직을 구현하는 것에 대한 구체적인 언급은 없지만, OrderProduct 사이의 관계를 중간 역할로서 OrderProduct 클래스가 어떤 식으로 연결되는지에 대한 설명이 포함되어 있어, 도메인 객체 내에서 관계를 설정하고 로직을 구현하는 데 참고가 될 수 있습니다.

  2. 내부적으로 orderProduct생기는 이유: 이 질문에서는 OrderProduct가 내부적으로 생성되는 원리와 CascadeType.ALL에 대한 이해를 돕고 있습니다. CascadeType.ALL이 더 범용적으로 사용되는지에 대한 궁금증에 부분적으로 답할 수 있습니다.

강의 내용과 질문을 통해 전반적인 개념 및 디자인 패턴 이해에 많은 도움이 되었다니 기쁩니다. Order 클래스 내에서 로직을 구현하는 것은 도메인 주도 설계(DDD)에서 말하는 리치 모델 접근 방식과 유사한데, 이는 도메인에 대한 로직을 가능한 한 가까이 위치시켜 도메인의 의미를 더 풍부하게 하고 유지보수를 용이하게 하는 것을 목표로 합니다. 현업에서도 상황에 따라 서비스 계층이 아닌 엔티티 자체에 비즈니스 로직을 넣어 리치 모델을 구현하는 방식이 종종 사용됩니다. 물론, 모든 경우에 최적의 방법인 것은 아닙니다. 팀 내에서 정하는 아키텍처 및 설계 원칙에 따라 달라질 수 있습니다.

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

junjun님의 프로필 이미지
junjun

작성한 질문수

질문하기