문제

편집자와 프로젝트의 개념을 가진 도메인 모델이 있습니다.

편집자는 여러 프로젝트를 소유하고 있으며 프로젝트에는 편집자 소유자뿐만 아니라 많은 편집자 회원도 있습니다. 따라서 편집자에게는 여러 가지 "가입 된"프로젝트가 있습니다.

나는 이것을 모델링하고 지속성을 위해 저장소 패턴을 사용하는 데 DDD 접근 방식을 취하고 있습니다. 그러나, 나는 어떻게 패턴을 잘 모르지만, 내가 어떻게 해야하는지 결정하기에 충분하지 않습니다.

나는 편집자와 프로젝트가 잠재적으로 동일한 집계에 있으며 루트가 편집기라는 가정을 연구하고 있습니다. 따라서 편집자를 얻은 다음 프로젝트를 열거하고 프로젝트의 회원 편집자를 열거 할 수 있습니다.

그러나 저장소에서 편집기를 검색 할 수 있다면,이를 소유 한 편집기를 얻을 때 저장소에서 모든 프로젝트를로드해야한다는 의미는 없습니까? 그리고 멤버 편집기를 게으른로드하려면 프로젝트에도 저장소에 대한 참조가 필요합니까?

또는 집계를 분할하고 편집기 리포지토리와 프로젝트 저장소가있는 경우 새 프로젝트가 편집기에 추가 될 때와 같이 두 가지에서 트랜잭션을 어떻게 처리해야합니까? 예를 들어:

Editor e = new Editor("Editor Name");
editorRepository.Add(e);

Project p = e.CreateProject("Project Name");
projectRepository.Add(p);    // These two lines
editorRepository.Save(e);    // should be atomic

저장소 패턴의 의도를 잘못 해석하고 있습니까?

도움이 되었습니까?

해결책

저장소 패턴의 의도를 잘못 해석하고 있습니까?

나는 "예"라고 말할 것입니다. 그러나 나와 내가 함께 일한 모든 사람이 같은 이유로 같은 것을 물었다는 것을 알고 있습니다 ... "당신은 4 차원으로 생각하지 않습니다, 마티".

조금 단순화하고 먼저 메소드를 작성하는 대신 생성자를 고수합시다.

Editor e = new Editor("Editor Name");
e = editorRepository.Add(e);

Project p = new Project("Project Name", e);
p = projectRepository.Add(p);

그 아래에서 프로젝트 저장소는 항상 유효한 소유자를 저장하고 있습니다 (p.EditorId) 프로젝트 데이터가 생성 된대로 프로젝트 데이터를 사용하지만 편집자 프로젝트를 다시 인구하면 거기에있을 것입니다. 그렇기 때문에 필요한 모든 속성을 생성자에 넣는 것이 좋습니다. 전체 객체를 전달하고 싶지 않다면 e.Id 할 것입니다.

그리고 멤버 편집기를 게으른로드하려면 프로젝트에도 저장소에 대한 참조가 필요합니까?

이제 주문시 편집자 프로젝트를 다시 인구하는 방법에 대해서는 원하는 일에 따라 몇 가지 선택 사항이 있습니다. 직선 저장소는 다음과 같이 원한다고 말합니다.

IEnumerable<Project> list = projectRepository.GetAllProjects()
                                .Where(x => x.editorId == e.Id);

하지만 어디에 넣을까요? 내부 프로젝트 나 편집자가 아니라, 당신이 옳거나, 그들은 저장소에 액세스해야하며, 그것은 좋지 않습니다. 위의 스 니펫은 느슨하게 결합되지만 그 자체로는 재사용 할 수 없습니다. 방금 저장소 패턴의 한계에 도달했습니다.

다음은 공유 리포지토리 소스와 함께 애플리케이션의 어댑터 레이어입니다.StaticServiceWrapper) 그리고 일종의 편집기 대상 개체 (또는 집계 또는 당신이 부르는 모든 것) 또는 이제 필요한 모든 저장소와 유창하게 대화 할 수있는 확장 방법을 혼합 할 수 있습니다. 나는 생산 시스템에서 이런 식으로 정확하게 수행하지 않았지만 간결한 예를 보여줍니다.

public static class Aggregators
{
    // one to one, easy
    public static Editor GetOwner(this Project p)
    {
        return StaticServiceWrapper.editorRep.GetEditorById(p.editorId);
    }

    // one to many, medium
    public static IEnumerable<Project> GetProjects(this Editor e) 
    { 
        return StaticServiceWrapper.projectRep.GetAllProjects()
                .Where(x => x.editorId == e.Id);
    }

    // many to many, harder
    public static IEnumerable<Editor> GetMembers(this Project p)
    {
        var list = StaticServiceWrapper.projectMemberMap.GetAllMemberMaps()
                        .Where(x => x.projectId == p.projectId);

        foreach ( var item in list )
            yield return StaticServiceWrapper.editorRep.GetEditorById(item.editorId);
    }
}

기본적으로 GetAll, GetByid, 추가, 업데이트, 객체 저장소 제거가 완료되면 연결을 내버려두고 어댑터 및 캐시 및 비즈니스 논리와 같은 재미있는 부품으로 객체/계층 계층을 위로 이동해야합니다 ("어머!").

다른 팁

책임을 편집자와 EditorMember로 나누는 것은 어떻습니까?

당신의 도메인을 알지 못하면, 그들이 다른 책임을 가질 것이라고 생각합니다. 예를 들어, 편집자는 매우 풍부 할 수도 있고 집계의 근본 일 수도 있지만 프로젝트는 회원에 대해 제한된 금액 만 알아야 할 수도 있습니다. EditorMember 객체는 상당히 가볍습니다.

이러한 도메인 객체는 사용자와 관련이있을 수 있지만 다른 맥락에있을 것입니다.

그것이 일을 도울 수 있습니까, 아니면 더 복잡하게 만들까요?

응용 프로그램의 요구에 따라 다릅니다. 주어진 편집자에 대한 모든 프로젝트를로드하는 것이 큰 문제라면 가상 프록시.

프로젝트의 멤버 편집자를 게으르게로드하는 것과 관련하여 가상 프록시를 사용하는 경우 프록시가 도메인의 일부로 간주되지 않기 때문에 편집기에 프록시를 주입하는 데 문제가 없습니다.

집계를 분할하면 작업 단위 원자력에 대한 하나의 솔루션으로 패턴. 그러나이 문제는 DDD에 고유하지 않으며 거래 행동을위한 다른 솔루션이 있다고 확신합니다.

여기에는 두 가지 다른 관계가 있습니다. 하나는 소유권과 멤버십을위한 두 가지 관계가 있습니다.

소유권 관계는 많은 것 (각 프로젝트에 대해 한 명의 소유자)과의 간단한 관계입니다. 회원 관계는 많은 사람들에게 많은 것입니다 (많은 편집자 프로젝트, 편집자 별 많은 프로젝트).

프로젝트 클래스에서 소유자 속성을 제공하고 특정 편집기가 소유 한 모든 프로젝트를 제공 할 수있는 ProjectRepository에 대한 메소드를 제공 할 수 있습니다.

많은 관계의 경우 프로젝트 클래스의 멤버 속성을 제공하고 특정 편집기를 포함하는 모든 프로젝트를 구성원으로 제공하는 Projectrepository의 방법을 제공하십시오.

또한 편집자와 프로젝트가 엔티티 인 것 같습니다. 아마도 집계를 나누었을 것입니다. 그러나 아마도 그 용어는 당신의 맥락에서 특정 의미를 가질 수있는 특정 의미를 가질 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top