2013-06-04 4 views
5

우리는 처음으로 프로젝트에서 도메인 기반 디자인을 채택하려고합니다. 내가 가진 문제는 엔티티 간의 연관성입니다. 당신은 어떻게 그들을 올바르게합니까?DDD에서 연결을 구현하는 올바른 방법은 무엇입니까?

말하면, 간단한 일대 다 연관 인 EmployeeContract 엔티티가 있습니다. 어떻게 모델링합니까?

옵션 1 : 집계.

문제 : 문제는 올바르게 이해하면 집계 개체를 만들 때 집계의 모든 항목을로드해야한다는 것입니다. 엔티티의 저장소를 참조해야 할 필요가 있기 때문에 필요한 경우 엔티티를로드 할 수 없습니다. 그러나 매번 직원의 계약서를 데이터베이스에서 가져 오는 것은 큰 성능 문제가됩니다.

옵션 2 : 저장소 (예를 들어, ContractRepository.GetContractsForEmployee())를 사용하고 Contract 클래스에 EmployeeId 속성을 추가하여 직원의 계약을 가져오고 있습니다.

문제점 : 엔티티에 비즈니스 로직을 넣기가 어렵습니다. 내가 방법을 가지고 싶습니다, 말하자면, Employee.Dismiss(),하지만 그것도 직원의 계약을 업데이 트해야합니다. 이것은 내가이 논리를 서비스에 넣어야한다는 것을 의미합니다. 문제는, 나는 단지 Employee에서만 작동하는 많은 로직을 생각할 수 없다. 따라서 모델은 서비스 내에서 대부분의 로직을 사용하여 약간 빈약해진다.

DDD에서 이러한 문제를 어떻게 처리합니까?

+1

DDD를 수행하지 않는 '간단한 일대 다 연관'을 생각하면 데이터베이스 스키마 디자인을 수행하고있는 것입니다. 엔티티 간의 연관성은 동작이어야합니다. 직원은 스스로를 해고 할 수 없으며 해고되어야합니다 (권한을 가진 다른 단체에서 해고해야합니다). 옵션 2가 올바른 옵션입니다. 엔티티에 대해 많은 동작이 필요하지 않습니다. 실제 도메인 비즈니스에서 도메인 객체가 매우 단순하다면 그렇게 할 수 있습니다. 도메인이 개념 (의미론)을 정의하고 오브젝트의 메소드 수를 정의하는 방법이 중요합니다. – MikeSW

+0

MikeSW가 맞습니다. DDD의 중요한 측면은 유비쿼터스 언어입니다. 도메인에 관해 말하는 방법은 도메인 전문가가 도메인에 관해 말하는 방법이어야합니다. 그렇지 않으면 코드가 어색하고 직관적이지 않게됩니다. 그것은 사소한 것처럼 들리지만,이 권리를 얻으면 엔티티는 행동을 제안하기 시작합니다. 예 : Employee.Resign(); Contract.Terminate(); – Asher

답변

2

이것은 도메인을 알지 못해서 내 걸릴뿐입니다.

먼저 here은 읽을 수있는 좋은 자료입니다 (골재 및 뿌리 부분).

DDD 용어에서 EmployeeContract은 모두 엔터티입니다 (둘 다 ID가 있기 때문에). . 각 집합체 집계 밖에 어떤 개체에 대한 참조를 유지하도록 허용되는 골재의 유일한 구성원 루트 엔티티 갖

"응집체 하나 이상의 엔티티 또한 및 주위의 경계를 그린다.? 다른 도메인 기관도 contract에 대한 참조를 가질 수 있기 때문에 Employee은, 분명히하지 루트 개체 인으로 집계 EmployeeContract 양식을 수행하고 계약의 ID 년대는 전 세계적으로 고유하지 않습니다 "

질문은 . 단지 내 Customer 그래서

을 고려하여이 규칙은 EmployeeContract 모두 집계 뿌리는

다음 :. "만 집계 뿌리는 쿼리를 통해 직접 얻을 수 있습니다. 그래서 이것은 우리가 집계 루트 당 저장소를 가져야한다는 것을 의미한다. "이 경우에 따라서

, 우리는 EmployeeRepositoryContractRepository 있습니다.

계정으로이 모든 것을 가지고 가서, 나는 사이의 관계를 추가 할 것 직원 및 계약을 도메인 모델에서 처리하지만 별도로 처리해야합니다. 결국 Employee이 필요하면 반드시 contracts이 필요하지는 않습니다. 둘 다 다른 측면입니다.

옵션 2는 내가 선택한 것입니다. ContractRepository을 사용하여 관심있는 계약서를 받으십시오. 필요한 경우 uld는 필요한 경우 직원 및 계약을 집계하는 도메인 서비스를 추가합니다.

Company 엔티티도 정의하는 경우 직원을 해고하는 것은 해당 엔티티의 작업 일 수 있습니다.

0

진정한 불변량을 찾아야합니다.

다음과 같은 불변식이있을 수 있습니다. 이미 닫은 Employee을 닫을 수 없습니다.

유일한 실제 불변량 인 경우 Employee 집합체를 만들 수 있습니다. 이는 연관 계약의 ID 만 가질 수 있습니다.

Contract은 (필요한 경우) 다른 집계가됩니다.

dismiss() 메소드가 성공하면 필요한 계약을로드하고 필요한 변경을 수행 할 수 있습니다.

1

우리는 최근 DDD 접근 방식을 채택했습니다. 나는 그것을 할 수 있다면, 내가 가진 것 (속성이 간결하게 단순화) 다음

public class Employee() { 

    String name; 
    Set<ContractNumber> contracts; 

    public void addContract(ContractNumber contractNumber) { 
     this.contracts.add(contractNumber); 
    } 

} 

public class Contract() { 
    ContractNumber contractNumber; 
    Date effectiveDate; 
} 

public class ContractNumber() { 
    String contractNumber; 
} 

ContractNumber는 직원 내에서 참조되는 값 개체입니다. 이 예에서 Employee는 Employees 및 해당 계약을 처리하는 BoundedContext 내에 있습니다. 다른 제한된 환경에서 Employee의 다른 표현이있을 수 있습니다.

다른 답변에서 논의 된 것처럼 직원과 계약서에 대한 리포지토리가 있습니다.

관련 문제