2016-06-08 6 views
0

나는 항목으로 구성된 인보이스 개체를 가지고 있으며 각 항목은 서비스와 관련이 있습니다.DDD 하위 개체 참조

다음과 같은 구조입니다.

{ 
    "invoiceId" : "dsr23343", 
    "items":{ 
     "id":1, 
     "service":{ 
     "serviceCode":"HTT" 
     } 
    } 
} 

내 요구 사항 중 하나는 항목이 우리 시스템에 존재하지 않는 서비스와 관련이 없어야한다는 것입니다. 제 생각에 도메인 객체는 결코 잘못된 상태로 들어선 안됩니다. 그래서 내가 뭐하는 거지 다음입니다 :

var service = new Service("SomeService"); 
var item = new Item(service); 
invoice.AddItem(item); 

내 질문은 내가 AddItem 기능은 서비스가 데이터베이스에 존재하지 않는 경우 두 번째 매개 변수 및 던져 예외로 저장소를받을 것을 요구해야한다?

+0

ServiceFactory를 사용하고 서비스를 검증 한 적이 있습니까? – Cerad

+0

서비스는 집계 루트입니까? – plalx

+0

항목이 송장에 추가 될 때까지 기다릴 필요가 없습니다. 해당 서비스가 유효하지 않은 경우 서비스 개체 자체 만들기 (시스템에 존재하지 않음) – falcon

답변

1

내 질문에 AddItem 함수가 리포지토리를 두 ​​번째 매개 변수로 받아야하고 서비스가 데이터베이스에없는 경우 예외가 발생해야합니까?

짧은 대답 : 확실하지 않습니까? 서비스 및 송장 같은 집합의 일부인 경우

긴 답변을 ...

것은, 그 저장소는 필요하지 않습니다 - 단지 골재의 상태를 봐주세요. 따라서 다음은 인보이스와 서비스간에 거래 경계가 있다고 가정합니다.

리포지토리를 인수로 사용하는 것은 너무 복잡합니다. Invoice는 서비스를로드 할 필요가 없으며 서비스 이 있는지 확인해야합니다.. 따라서 메서드 시그니처에 리포지토리를 배치하는 대신 "이 서비스가 있습니까?"를 지원하는 DomainService를 사용할 수 있습니다. 질문.

(DomainService의 구현은 아마도 저장소에서 조회를 수행 할 것입니다. 여기서는 마법을 사용하지 않습니다. Invoice를 구현 세부 사항에서 제외하면됩니다.)

서명 문서에서보다 제한적인 인터페이스를 사용하면 이러한 구성 요소간에 통합 계약이 무엇인지 명확하게 알 수 있습니다.

라고 말하면 요구 사항은 매우 의심 스럽습니다. 서비스 및 송장의 집계가 다른 경우 잠재적으로 수명주기가 다릅니다. 더 이상 존재하지 않는 서비스를 참조하는 항목이 포함 된 인보이스를로드하려고 할 때 어떤 일이 발생해야합니까? 그 유스 케이스가 폭발해야합니까? 그렇다면 문제를 해결하기 위해 인보이스를 편집하는 것이 어려울 것입니다 ....

인보이스에 항목을 추가하는 동안 다른 스레드가 서비스를 삭제하는 경우 ...?

검토 Udi Dahan의 에세이 : Race Conditions Don't Exist. 요약 - 모델이 마이크로 초 (microsecond)의 타이밍 변화에 민감한 경우 비즈니스를 모델링하지 않은 것일 수 있습니다.

당신은이 "불변"을 보호하기 위해 적어도 세 가지 대안을 가지고 있습니다.

하나는 클라이언트 수준입니다. 고객이 잘못된 서비스 코드를 생성하게하지 않으면이 문제가 발생하지 않습니다.입력 유효성 검사는 모델이 아닌 클라이언트 구성 요소 또는 응용 프로그램 구성 요소에 속합니다. 즉, 응용 프로그램이 프로세스 경계에서 이동 한 DTO에서 ServiceCode를 생성 할 때 확인할 수있는 일종의 것입니다.

하나는 모델의 다운 스트림입니다. 유효하지 않은 서비스 코드를 참조하는 송장 항목을 감지 할 수 있으면 예외 보고서를 브로드 캐스트하고 비상 대응 프로세스를 사용하여 문제를 관리하십시오. 희소하고 탐지하기 쉽고 수정하기 쉬운 일관성 문제는 도메인 모델에서 엄격한 유효성 검사가 필요하지 않습니다.

하나는 모델 자체에 포함됩니다. 인보이스 항목 작성이 서비스 수명주기와 밀접하게 결합 된 경우 인보이스가 아닌 서비스가 항목을 생성 할 수 있습니다. 예를

를 들어
class Service { 
    reportUsage(Customer, TimePeriod) 
} 

특이한 찾고 서명하지 않을 것이고, 당신은 아마 도메인 이벤트를 발생 서비스가 제대로 자신의 ServiceCode를보고려고하고 있다는 것을 확신 할 수 있습니다.

+0

클라이언트 수준에서 유효성 검사에 대한 솔루션이 마음에 들지만 도메인 개체는 잘못된 상태로 들어갈 수 있습니다. 나는 비즈니스 요구 사항에 따라 타협을해야한다고 생각한다. – Robert

+0

@Robert 비즈니스 질문을 제기해야합니다. 존재하지 않는 서비스에 대한 항목을 추가하면 어떻게됩니까? 대개 이러한 작업을 수행하면 어딘가에서 "SomeService"문자열을 얻습니다. 따라서 아마도 명령이 형성된 순간에 존재했을 것입니다. 이것은 앞에서 언급 한 질문을 완전히 유효하게 만들고 "유효하지 않은 상태"가 아니므로 처리해야 할 상태입니다. 또한 DDDx Greg Young의 over-engineering에 대한 언급을 참고하여 이것이 발생할 확률을 계산하십시오. –