작성
·
35
0
안녕하세요 토비님 가의 잘 보고 있습니다. DDD는 처음이고 헥사고날방식도 처음이라 질문 수준이 낮은 점 양해 부탁드립니다!
이 강의까지 보고나서 전체코드를 봤을떄 궁금한 점들이 있어서 질문 드립니다!
1번 질문:
@Entity
public class Member {
@Embedded
private Address homeAddress;
}
@Embeddable
public class Address {
private String city;
private String street;
private String zipcode;
}
@Embeded사용할때 데이터 필드를 의미 있는 하나의 묶음 이라는 의미로 사용하는데 profile 이나 email같은 경우에는 컬럼이 하나여도 @Embeded 로 묶으셨는데 그 기준(언제 사용해야하느지)가 궁금합니다. 저라면 그냥 생각 없이 String 으로 받았을거같은데 ….!
2번 질문 : Aggregate root 로 접근해하면 메서드 체이닝 비슷하게 일어나는거 같은데 그런 점은 괜찮나요!?
3번 질문 :. Aggreagate root로 접근하는 방식은 DDD에서만 사용하는지 ?? 기존 JPA + 레이어 아키텍쳐에서도 사용이 가능한건지....?
4번 질문 : 강의에서는 1:1 이였지만 , ManyToOne 단방향 , ManyToOne OneToMany 양방향 관계에서도똑같이 Aggregate root로 접근해서 데이터를 처리해야하는지..?
미리 감사드립니다!!
답변 2
0
안녕하세요.
1번은, @Embedded는 기본 타입이 아닌 사용자 정의 타입(클래스)으로 값 객체를 만들 때 주로 사용합니다.
이렇게 하면 개념적인 명확성을 줄 수 있습니다. String email과 Email email은 코드를 읽을 때 뿐 아니라 이게 파라미터로 전달 되거나 사용되어질 때, 비록 String 하나 뿐이더라도, 이게 어떤 타입이고 어떤 정보가 저장되는지가 명확하게 드러납니다.
또, 유효성 검사와 변환, 기타 이 값을 사용하는 로직을 담은 메소드를 하나의 클래스에 모아둘 수 있어서 응집도가 올라갑니다. Member 클래스에 isValidEmailAddress()가 있는 것보다는 Email 클래스에 있는 게 낫겠죠. Email처럼 여러군데 사용될 가능성이 있는 경우엔 중복도 피할 수 있고요.
파라미터로 넘길 때 자연스럽게 타입 안정성도 보장됩니다. String은 너무 많이 쓰이자나요. 그런데 email을 넘겨야 하는데, 사용하는 쪽에서 실수로 name을 넘겨도 컴파일도 잘 되고 기능도 돌아갑니다. 실제 메일 발송을 해야 없는 메일이라는 경고가 뜰 뿐이죠. 이런 논리적인 버그를 피하는데도 도움이 됩니다.
따라서 여러 개의 함께 다니는 정보를 묶는 경우에도 쓰지만 값 객체가 가지는 장점을 살리기 위해서도 타입을 클래스로 정의하고 @Embedded로 쓸 수 있습니다. User type을 정의하는 복잡한 방법도 있는데 그 보다는 임베딩 시키는게 깔끔하죠.
2번은 애그리거트에 여러 엔티티가 연결되어 있는 경우에 단순 조회라면 체이닝을 써도 괜찮습니다. 코드도 자연스럽게 읽히죠. getMember().getAddress().getStreet() 뭐 이런 식이죠. 중간에 널이 들어갈 수 있다면 Optional로 안전하게 호출할 수도 있습니다.
반면 로직을 적용해서 변경이 일어나는 작업인 경우, 또는 어떤 조건 판단을 위한 메소드를 호출하는 경우라면 로직을 루트에 두고 루트가 내부 체이닝 구조에 따라서 필요한 기능을 수행하고 리턴하게 하는 것이 바람직합니다. 그러면 나중에 내부 구조의 변경이 일어나도 사용하는 코드를 수정할 필요가 없고, 내부 엔티티가 불필요하게 노출이 되어서 그 내부 기능을 바로 사용하는 것도 피할 수 있겠죠.
3번은 애그리거트라는 용어는 DDD 책을 통해서 처음 소개된 것으로 알고 있습니다. 하지만 이렇게 항상 하나의 트랜잭션으로 묶여서 처리되거나 내부를 공개하지 않는 것이 더 나은 설계인 경우엔 유사한 방식을 얼마든지 따를 수 있습니다. 단순하게 데이터 저장 기술로 JPA를 쓰는 경우에도 애그리거트처럼 cascade를 적극적으로 활용하는 예는 아주 많습니다.
4번은 경우에 따라 다릅니다. 관계가 어떻게 되어있는지는 중요하지 않습니다. 각 엔티티의 의미와 변경 주기, 시점, 방식에 따라서 애그리거트를 어떻게 묶을지는 고민해봐야죠. 그리고 애그리거트를 묶는 단위는 시간이 지나고 바뀔 수도 있습니다. 모든 걸 처음부터 완벽하게 설계하라는 보장은 없으니까요. 좀 애매하다 싶으면, 우선 결정을 하나 해보고, 코드가 발전하면서 그 선택이 어떤 영향을 주는지 보고 나중에 리팩터링해도 됩니다. 중요한 건 도메인 모델을 더 깊이 연구해보는 것이죠.
0
안녕하세요, 인프런 AI 인턴입니다. wnsqud70님!
강의를 통해 도메인 주도 설계(DDD)와 헥사고날 아키텍처에 대해 공부하시며 여러 가지 질문을 남겨주셨네요. 아래에서 각각의 질문에 대해 답변드리겠습니다.
@Embedded
와 @Embeddable
어노테이션은 JPA에서 서로 관련있는 여러 필드를 하나의 객체로 묶을 때 유용하게 사용됩니다. 필드가 하나뿐인 경우에도 해당 필드가 의미적으로 별도의 개념이나 엔티티로서의 역할을 갖는 경우 @Embedded
를 사용하는 것이 좋습니다. 예를 들어, Email
은 단순히 문자열이지만 자신만의 유효성 검증 로직을 가질 수도 있고, 도메인에서 중요한 역할을 할 수 있습니다. 따라서 이러한 의미적 그룹핑은 코드의 가독성과 유지보수성을 높이는 데 도움을 줍니다.
애그리거트 루트(Aggregate Root)를 통해 연관된 엔티티들에 접근한다는 것은 DDD에서 권장되는 방식입니다. 메서드 체이닝은 편리성을 제공하지만, 이를 남용하면 복잡도가 증가할 수 있습니다. 따라서 애그리거트 내의 불변성과 일관성을 유지하는 데 주의를 기울이는 것이 중요합니다.
DDD에서는 특히 애그리거트 루트를 통한 접근 방식을 강조하지만, 이는 다른 아키텍처에서도 관련성 있는 엔티티들을 관리하는 데 유용하게 사용할 수 있습니다. JPA와 레이어드 아키텍처에서도 애그리거트 접근 방식을 사용하여 계층 간의 결합도를 낮출 수 있으며, 도메인 로직을 명확하게 할 수 있습니다.
ManyToOne이나 OneToMany와 같은 관계에서도 애그리거트 루트를 통해 접근하는 것이 권장됩니다. 이는 데이터 일관성을 한 곳에서 관리할 수 있도록 돕기 때문입니다. 그러나 고복잡도의 관계 설정에서는 엔티티 간의 관계와 그에 따른 데이터 변경을 신중하게 관리해야 함을 염두에 두어야 합니다.
관련된 내용은 다음 게시물들을 통해 더 깊이 이해할 수 있습니다:
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.