1

은 이러한 논쟁에서에 계속 :도메인 Enties 액세스 저장소는

DDD - the rule that Entities can't access Repositories directly

Is it ok for entities to access repositories?

는 도메인 저장소에 액세스 할 수 더 나은 느낌이 어떤 상황이 여전히있다.

public class TaskStatus 
{ 
    public long Id {get;set;} 
    public string Description {get;set;} 
} 

public class Task 
{ 
    public long Id {get;set;} 
    public string Description {get;set;} 
    public TaskStatus Status {get;set;} 

    public void CompleteTask() 
    { 
     ITaskStatusReposity repository = ObjectFactory.GetInstace<ITaskStatusReposity>(); //Or whatever DI you do. 
     Status = repository.LoadById(Constants.CompletedTaskStatusId); 
    } 
} 

내가 CompletedTaskStatus 및 OpenTaskStatus 객체를 가질 수 알고 있지만이 unnessacery 것와 이어질 수있는 상황이있다 : 내가보고 목적에 대한 설명을 포함하는 데이터베이스의 TaskStatus 테이블을 필요로 가정하는,이 예제를 가지고 계급 폭발에.

그리고 어쨌든 왜 이런 종류의 일이 아니라면 왜 저장소 인터페이스가 도메인에 저장되어 있습니까?

답변

3

엔티티가 리포지토리에 액세스해도 괜찮습니까?

아니요. 제발하지 마세요.

도메인 모델의 개념은 비즈니스 로직을 응용 프로그램과 분리하는 것입니다. db, 리포지토리 및 응용 프로그램에서 격리하십시오. 따라서 비즈니스 로직을 별도로 유지하고 응용 프로그램과 별도로 테스트하고 변경할 수 있습니다.

도메인은 데이터 지속성을 완전히 인식하지 못하고 자동으로 발생한다고 가정해야합니다.

ddd-the-repository-pattern.aspx

둘째 당신의 enties로 저장소를 주입되지 않은 다른 실제적인 이유가있다.

  1. 엔트리는 저장소에 종속성을 생성 한 엔티티에 저장소를 삽입하여 단위 테스트 가능해야합니다.

  2. GetInstance() 메서드를 사용하면 Demeter의 법칙이 깨지므로 ITaskStatusRepository를 사용자 엔터티에 밀접하게 결합하게됩니다. 새로운 Task를 생성하고 단위 테스트를 작성할 때 Task가 ITaskStatusRepository를 필요로한다는 것은 분명하지 않습니다. 따라서 비즈니스 논리를 단위 테스트하는 것이 더 어려워집니다.

  3. DDD 관점에서 저장소는 DB와의 인터페이스에만 관심이있을뿐만 아니라 메모리 저장소에서 검색 할 수도 있습니다. 또는 목록.

  4. 저장소가 테이블과 1 : 1 관계 일 필요는 없습니다. 태스크 레파지토리가 다른 테이블과의 내부 조인을 수행하여 복잡한 쿼리를 수행하고 태스크 항목 목록을 리턴해야하는 경우 해당 쿼리를 수행하는 리포지토리의 메소드를 노출합니다. (나는 이것이 저장소 패턴의 일반적인 오해라고 생각한다).

  5. 엔티티는 db에 대한 작업 수행에 신경 쓰지 않아야합니다.

여기에 게시 된 이미지를 참조하십시오

DDD: how the layers should be organized?

public class TaskStatus 
{ 
    public long Id { get; set; } 
    public string Description { get; set; } 

    public TaskStatus() { 
     Description = "Incomplete"; 
    } 
} 

public class Task 
{ 
    public long Id {get;set;} 
    public string Description {get;set;} 
    public TaskStatus Status {get;set;} 

    public void CompleteTask() 
    {   
     Status.Description = "Complete"; 
    } 
} 

를 응용 프로그램 계층 내부 저장소는 지속성 (여부)에 대한 책임이 있습니다. 저장소는 집계 루트의 목록 <입니다. 그리고 그것은 전체 루트 레벨에서 작동합니다.

TaskService에서 작업을 사용하는 예입니다. 서비스는 응용 프로그램 계층의 엔터티에서 작동합니다.

public class TaskService 
{ 
    private readonly ITaskRepository _taskRepository; 

    public TaskService(ItaskRepository taskRepository){ 
     _taskRepository = taskRepository; 
    } 

    public List<Task> CompleteAllTasks() 
    { 
     List<Tasks> getTasks = _taskRepository.GetTasks(); 
     getTasks.ForEach(CompleteTask); 
     return _taskRepository.Save(getTasks); 
    }  
} 
+0

1 + 2 : ITaskStatusRepository에 액세스하여이 도메인은 지속성의 본질을 인식하지, althought 나는 지속의 존재를 인식하고 동의합니다. 확실히 저장소가 조롱받을 수 있기 때문에 단위 테스트가 가능합니까? 나는 당신이 내가 무엇을하려고 노력하고 있는지를 당신이 어떻게 얻을 것이라고 제안하고 있는지 확실하지 않습니다. –

+0

3 : 데이터베이스에 액세스하는 것 외에 내 리포지토리가 무엇을하고 있는지 잘 모르겠습니다. 4 : 좋아, 그래서 TaskStatus는 열거 형일 수 있고 'public void Complete() {Status = TaskStatus.Complete; } '이고 StatusDescription은 Task의 속성이어야합니까? –

+0

내가 잘못 이해하지 않는 한, 'CompleteTask'는 저장소에있는 것입니다. 내 exampl은 매우 사소한 것이며, 유일한 비즈니스 논리는 작업이 완료되면 상태가 '완료 됨'으로 변경된다는 것입니다. 이 논리는 훨씬 더 복잡 할 수 있으며 저장소에서 확실히 수행되지 않아야합니다. –

관련 문제