1

컨텍스트 :
엔티티 북이 있습니다. 책은 하나 이상의 설명을 가질 수 있습니다. 설명은 값 개체입니다.값 개체 관계를 모델링하는 방법은 무엇입니까?

문제 :
에 대한 설명은 다른 설명보다 더 구체적 일 수있다. 예를 들어 설명에 책의 내용이 포함되어 있고 표지가 어떻게 보이는지는 표지의 모양 만 설명하는 설명보다 더 구체적입니다. 이 모델을 만드는 방법과 리포지토리에 저장하는 방법을 모르겠습니다. 이러한 관계를 아는 것은 책이나 책 설명의 책임이 아닙니다. 어떤 다른 객체는 이것을 처리 한 다음 저장소에 관계를 저장하도록 요청할 수 있습니다. 그러나 BookRepository.addMoreSpecificDescription (Description, MoreSpecificDescription)은 저장소가 저장하기가 어려워 보입니다.

DDD에서 어떻게 처리됩니까?

답변

7

다른 두 응답은 한 방향 (+1 BTW)이다. 나는 원래의 질문에 편집 한 후에 들어 오니 여기에 내 두 센트가있다 ...

값 개체를 다른 엔터티간에 공유 할 수있는 두 개 이상의 속성이있는 개체로 정의합니다. 하나의 집계 루트 내에서만 공유 할 수 있습니다. 그들이 공유 할 수 있다는 사실.

이 예제를 사용하려면 값 개체로 "설명"을 정의합니다. 여러 속성이있는 '설명'은 여러 장부에서 공유 할 수 있습니다. 현실 세계에서는 책을 저술하거나 출판 한 사람의 주인이 각 책마다 고유 한 설명을 가지고 있음을 모두 알고 있기 때문에 의미가 없습니다. Hehe. 그래서 Descriptions은 Value Object가 아니지만 Book Aggregate Root Entity 경계 내에 추가 Entity 객체가 있습니다 (단일 집계 루트 엔티티 내에 여러 엔티티가있을 수 있음). 재발행 된 도서, 최신 개정판 등은 약간의 변화를 설명하는 약간 다른 설명을 가지고 있습니다.

나는 그 질문에 대답 생각 - (예를 들어, Book.GetDescriptions()를 ...) 설명 엔티티 객체를 만들고 메인 도서 법인 집계 루트 뒤에 그들을 보호 할 수 있습니다. 이 답변의 나머지 부분에서는이 게시물을 읽는 다른 사람들을 위해 Repositories에서 Value Objects를 처리하는 방법에 대해 설명합니다.

값 개체를 리포지토리에 저장하고 검색 할 때 나는 자신과 씨름했던 동일한 영역을 침범하기 시작합니다. "데이터베이스 우선"모델링 방식에서 DDD 방식으로 전환했을 때. 나 자신은 DB에 값 객체를 저장하는 방법과 ID없이 검색하는 방법에 대해이 글을 읽었다. 내가 뒤로 물러나서 내가하고있는 것을 깨달을 때까지 ...

도메인 기반 디자인에서는 데이터 저장소가 아닌 도메인의 값 개체를 모델링합니다. 이것이 핵심 구절입니다. 즉, 데이터 저장소에 독립 개체로 저장되도록 값 개체를 디자인하지 않는다는 의미입니다. 원하는 개체는 저장할 수 있습니다.

값 객체의 일반적인 DDD 예제 인 Address()를 살펴 보겠습니다. DDD는 우편물 주소가 완벽한 가치 객체의 예임을 제시합니다. 왜냐하면 값 객체의 정의는 객체의 고유성을 창출하기 위해 속성의 합계가되는 객체이기 때문입니다. 속성이 변경되면 다른 값 개체가됩니다. 그리고 그것의 속성의 동일한 값 객체 9teh 합계)는 다른 엔티티들간에 공유 될 수 있습니다.

우편 주소는 지구상의 특정 위치의 긴/위도를 나타내는 위치입니다. 여러 사람이 주소에서 살 수 있고, 누군가 움직이면 동일한 우편 주소를 사용하는 새로운 사람들이 이제 동일한 값 개체를 사용합니다.

그래서 주소 정보가있는 MailingAddress() 개체가있는 Person() 개체가 있습니다. 그것은 Person() 집계 루트 뒤에 get/update/create 메소드/서비스로 보호됩니다.

이제 어떻게 저장하고 동일한 가정의 사람들에게 나누겠습니까? 아, DDD가 거짓말입니다. DDD에서 바로 데이터 저장소를 모델링하지는 않습니다 (비록 좋을지라도). 그렇게 말하면 Person 객체를 나타내는 하나의 Table을 간단하게 만들 수 있으며, 그 안에는 우편 주소에 대한 열이 있습니다. 리포지토리에서 데이터 저장소의 Person() 및 MailingAddress() 객체로 해당 정보를 다시 수화하고 Create/Update 작업 중에 데이터를 분할해야합니다.

네, 데이터 저장소에 중복 된 데이터가 있습니다. 같은 우편 주소를 가진 세 명의 Person() 엔티티는 모두 Value Object 데이터의 세 복사본을 가지고 있습니다. 값 객체는 쉽게 복사되고 제거됩니다. "복사"는 DDD 지침서에있는 최적의 단어입니다.

그래서 요약하면 Domain Drive Design은 도메인의 모델링을 통해 실제 비즈니스 사용을 나타냅니다. Person() 엔티티와 MailingAddress Value Object는 응용 프로그램에서 다르게 표현되므로 별도로 모델링합니다. 복사 한 데이터는 Person 테이블과 동일한 테이블에 추가 컬럼으로 유지한다.

위의 모든 사항은 엄격한 DDD입니다. 그러나 DDD는 단지 "제안"일 뿐이며 살아갈 규칙이 아닙니다. 그래서 당신 자신과 다른 많은 사람들이 해왔 던 일을 자유롭게 할 수 있습니다. 일종의 느슨한 DDD 스타일입니다. 복사 된 데이터가 마음에 들지 않으면 유일한 옵션은 MailingAddress()에 대한 별도의 테이블을 만들고 Identity 열을 그 위에 붙일 수 있고 MailingAddress() 개체를 업데이트하여 이제 해당 ID를 갖게 할 수 있다는 것입니다. (개인적으로는 제 3의 다 대다 관계 테이블을 좋아해서 쿼리의 속도를 높이기 위해) 그 ID를 공유하는 다른 Person() 객체에 연결하기 위해서만 그 ID를 사용한다는 것을 알고 있습니다. Idenity (내부 수정 자)가 Aggregate Root/Domain 외부로 노출되지 않도록 마스크해야합니다 (가능한 경우 Application 또는 UI와 같은 다른 계층은 MailingAddress의 Identity 열을 알지 못합니다). 또한 MailingAddress 용 전용 저장소를 만들고 PersonService 계층을 사용하여 올바른 개체 인 Person.MailingAddress()에 결합합니다.

미안하지만 ... :)

4

우선 리뷰는 항목이어야한다고 생각합니다.

둘째, 당신은 왜 리뷰 간의 관계를 모델링하려고? 나는 그들 사이의 자연스러운 관계를 보지 못한다. "보다 구체적"은 너무 모호하여 관계로 유용하지 않습니다. 당신이 상황을 모델링하는 데 문제가있는 경우

, 그건 어쩌면 아무 관계가 없다는 것을 의미한다.

+0

참고 : 리뷰 대신 설명을 사용하여 예를 들어 보았습니다. 그 관계는 자연스럽지 않다고 생각합니다. 사용자가 요약을 표시하는 설명을보고 싶어한다고 가정 해 보겠습니다. 그런 다음 요약을 보여주는 설명이 적합합니다. 그게 내가 말하는 '보다 구체적'입니다. – koen

1

나는 Jason에게 동의합니다. 나는 당신의 이론적 근거가 객관적인 가치 평가를 위해 무엇인지 모릅니다.

BookReview가 BookReviewContentItems를 가지고 있기 때문에 BookReview의 메소드가 충분히 구체적인지 결정할 수 있으므로 메소드가 해당 컨텐츠 항목의 컬렉션을 쿼리하여 결정할 수 있습니다.

+0

그들은 변하지 않는다는 것이 이론적 근거입니다. 서평이 잘못 선택되었습니다. 예제에서 책 설명이 더 잘 맞을 것입니다.책 설명은 신원을 신경 쓰지 않는 메타 데이터입니다. 예제를 업데이트하겠습니다. – koen

관련 문제