2012-02-20 3 views
7

우선 정답은 없을 것입니다.하지만 저보다 많은 것을 알고 도움을 줄 수있는 사람들이있을 것입니다.DDD - 엔티티 당 저장소 또는 모든 저장소?

사용자, 블로그, 게시자가 3 개 있습니다.

시스템에는 여러 사용자가있을 수 있습니다.

사용자는 여러 개의 블로그를 가질 수 있지만 각 블로그는 한 명의 사용자 만 가질 수 있습니다.

블로그에는 사용자가 게시 할 게시물이 여러 개있을 수 있으며 모든 게시물은 블로그를 소유 한 동일한 사용자의 게시물입니다 (예 : John이 Food를 소유 한 경우 John 만이 블로그에 게시 할 수 있음). 물론 각 게시물에는 하나의 상위 블로그가 있습니다.

그런 다음 모든 사용자 세부 정보, 모든 블로그 이름 및 마지막 5 개 게시물을 표시하려는 사용자 프로필 페이지가 있습니다.

다음 블로그의 세부 정보, 소유자 (사용자)의 이름 및 모든 게시물의 제목을 표시하는 블로그 페이지가 있습니다.

그런 다음 게시 세부 정보, 블로그 이름 및 소유자 이름을 표시하는 게시 페이지가 있습니다.

내가 알기로 나는 그들 모두 사이의 관계가 있지만, 그들 중 누구도 집합체로 행동 할 수 없다.

코드에서 엔티티를 정의하는 것이 그리 어렵지 않습니다. 저장소를 정의하는 데 문제가 있습니다. 얼마가 필요합니까? 3 - 각 엔티티 당 하나? 1 - 모든 걸? 조회는 어떻게 수행합니까?

예를 들어 사용자 페이지에 마지막 게시물 5 개를 가져 오는 것입니다. 사용자는 게시물에 대한 참조가 없으며 대신 각 블로그가 게시물의 컨테이너를 보유하는 블로그의 컨테이너를 보유합니다. 내 저장소에 UserID를 허용하고 게시물 목록을 반환하는 메소드가 있어야합니까? 아니면 서비스가되어야할까요? 또한 일반적으로 모든 데이터로드를 수행하지는 않지만 대신 게으른로드가 있습니다. 기존 User 엔티티를 검색하면 필요할 때가 지 (처음 액세스 할 때) 블로그를로드하지 않습니다.

미리 감사드립니다.

+0

'저장소'대 '서비스'는 정확히 무엇을 의미합니까? IMO는이 질문에 너무 광범위합니다. – home

+0

정의는 http://en.wikipedia.org/wiki/Domain-driven_design에서 찾을 수 있습니다. 그렇지만 나는 그 질문이 너무 넓어서 조금은 두려웠습니다. –

답변

4

내가 만들 것 포스트 리포지토리를 제거하고 게시물을 처리하십시오. BlogRepository

필자는 보통 저장소를 사용한 후에 저장소를 모델링하고 집계의 중첩 (두 단계 이상)을 방지합니다.

예를 들어 사용자 페이지에 마지막 게시물 5 개를 가져 오는 것입니다. 사용자는 게시물에 대한 참조가 없으며 대신 각 블로그가 게시물의 컨테이너를 보유하는 블로그의 컨테이너를 보유합니다.

사용자는 Blog에 대한 컨테이너가 없어야합니다. 가져 오기 저장소가 있습니다.

사용자 ID를 허용하고 게시물 목록을 반환하는 저장소가 있어야합니까?

예.

아니면 서비스가되어야할까요?

서비스는 도메인 모델을 사용하는 코드에서 비즈니스 논리를 제거하는 데 사용됩니다. 그런 종류의 논리를 얻을 때까지는 생성하지 마십시오.

또한 일반적으로 모든 데이터를로드하지 않지만 대신에 느린 로딩을 수행합니다. 기존 User 엔티티를 검색하면 필요할 때가 지 (처음 액세스 할 때) 블로그를로드하지 않습니다.

모든 도메인 모델을 함께 연결하는 등록 정보가 없으므로 지연로드를 피할 수 있습니다. 자식 집계에 대한 속성 만 갖도록하십시오.

+0

코멘트 주셔서 감사합니다!재미있는 해결책은 아프다. 중첩 집계는 피하려고하지만, 항상 그렇게 간단하지는 않습니다. –

+0

@skwee : 내 업데이트를 읽으십시오. – jgauffin

+0

감사합니다. 훨씬 더 깨끗하고 도움이됩니다! 나는 단 하나의 질문 : 왜 사용자가 블로그 컨테이너를 가져서는 안되는가? 귀하의 대답을 통해 전체 프로세스가 명확하게 단순화되지만 그 이유는 알 수 없습니다. 나는 당신의 마음 상태가 "블로그 컨테이너를 가져 오는 것이 블로그를 가져 오는 것을 복잡하게 만들고 게으른 로딩을 구현할 필요가 있기 때문에, 사용자 컨테이너에서 블로그 컨테이너를 갖지 않기로 결정한 이후"와 같은 것이 아니라고 확신합니다. 이 결정 뒤에는 몇 가지 논리 또는 규칙이 있어야합니다. 나는 그것을 알고 싶다. 감사! –

0

사용자는 종종 일반적인 집계 루트입니다. 사용자 집합은 사용자 기본 설정, 사용자 통계, 심지어 블로그까지 포함 할 수 있습니다.

또한 게시물 주위에 많은 것들이있는 집계 루트에 대한 좋은 후보가 나타납니다 : 댓글, 태그, 카테고리 ... 당신은 PostRepository.LoadByBlog() 또는 PostRepository.LoadByUser()를 사용할 수 있습니다. 페이지.

이제 설명 된 것으로부터 추론 된 것은 하나뿐입니다. 모든 도메인은 고유하므로 우리가 알지 못하는 게임 변경 정보가있을 수 있습니다.PostRepository이 게시물을 처리하는 데 사용

  • BlogRepository 당신이 내가 것 코멘트를 지원하지 않을 경우
  • UserRepository

검색에 주로 사용 코멘트 :

+0

당신의 의견을 보내 주셔서 감사합니다! 그러나 내가 설명한 영역을 고수하게하십시오. 다른 엔티티 (태그, 카테고리)를 추가하는 순간 도메인이 크게 변경되며 이는 좋지 않습니다. 내가 설명한 도메인은 내가 소유하고있는 도메인이며 이것은 내 질문에서 제기 된 도메인입니다. 나는 복잡한 도메인을 만들기 위해 DDD에서의 경험이 부족하기 때문에 나는 (아직) 복잡하게하고 싶지 않기 때문에 의도적으로 상대적으로 단순한 도메인을 골랐다. –

+0

그럼에도 불구하고, 나는 여전히이 2 개의 집계 루트와 해당 리포지토리를 보유 할 것입니다. 사용자 아이디를 URL 등에서 입력으로 받았다고 가정하면 UserRepository.LoadById()는 트릭을 사용하여 사용자 세부 정보를 표시합니다. 여기에서 사용자의 블로그로 이동하여 제목을 얻을 수 있으며 PostRepository.LoadLatestFiveByUserId()는 가장 최근 게시물 5 개를 제공합니다. 그런 다음 다른 페이지에는 PostRepository.LoadAllByBlog() 및 PostRepository.LoadById()를 사용할 수 있습니다. – guillaume31

+0

URL에 대해 정확하게 추측했습니다. 나도 같은 솔루션 (다소)에 대해 힘들지만 내 솔루션에서 BlogRepository하지만 많은 코드 (예 : BlogRepository.GetById()는 UserRepository.GetById()는 블로그와 사용자를로드해야합니다.)는 사용자와 블로그를로드하여 같은 기능을 2 개의 저장소에 복사합니다. –

1

나는 저장소가 있는지 여부를 결정하기 전에 엔티티의 중요성을 살펴볼 것입니다.

테스트 중심 개발 측면을 살펴보면 각 엔티티에 대한 저장소가 있습니다. 이 방법을 사용하면 IUserRepository, IBlogPostRepository 등의 가짜 구현을 할 수 있습니다.이 접근법은 단위 테스트를 촉진하고 저장소의 구현을 다른 것으로 대체 할 수있게합니다.

그러면 내 기분이 좋을 때 내 리포지토리를 서비스로 그룹화 할 것입니다. 이렇게하는 한 가지 방법은 사용 사례를 작성하고 요구 사항에 적합한 방식으로 그룹화하는 것입니다.

예를 들어, 나는 사용자가 다음과 같은 작업을 수행 할 수 있음을 말할 수있다 :

  1. 게시물보기
  2. 제출 후
  3. 지금 볼 수있는 IUserService을 할 수

편집 포스트 , 게시물 제출 및 수정. 이 서비스는 내 리포지토리를 집계 (그룹화)합니다.

결국 다음을 수행 할 수 있습니다.

var blogPost = new BlogPost(); 
ServiceFactory.Resolve<IUserService>(c => c.SubmitPost(blogPost)); 

이제이 방법 중 하나입니다.

또는 IBlogPostService를 사용하면 매우 유사한 동작이 나타나거나 저장소를 사용하고 집계 서비스를 구현하지 않을 수 있습니다. 나는 "만들기 위해 노력하고

포인트, 당신은 작은 세부 사항에 끊지 것을.이 비슷한 동작을 달성 일반적으로 여러 가지 방법이 있으며, 당신이 배울 수있는 유일한 방법은 연습에 의해입니다.

만들기 리포지토리를 재사용 할 수는 있지만 자네가 무언가를 과도하게 엔지니어링했는지 스스로에게 물어 본다. 즉, 나는이 리포지토리를 독자적으로 사용할 것인가? 예를 들어 리포지토리가 거의 없으면 집계 서비스로 랩핑하십시오.

3 개 이상 (임계 값은 전적으로 귀하에게 달려 있습니다) 리포지토리를 선택한 다음이 서비스를 두 개의 개별 서비스로 리팩토링하는 것을 고려하십시오.

도움이되기를 바랍니다.