2010-03-30 4 views
2

계약 관리를위한 데이터 모델 설계에 대한 조언을 찾고있었습니다. 따라서 계약의 일반적인 수명주기는 다음과 같습니다.(실제) 계약을 처리하는 데이터 모델을 설계하는 방법은 무엇입니까?

  • 계약서가 작성되어 "초안"상태입니다. 내부적으로 볼 수 있으며 변경 될 수 있습니다.
  • 계약이 공급 업체로 넘어 가고 상태가 "보류 중"으로 설정됩니다.
  • 공급 업체가 계약을 거부합니다. 이 상태에서 아무 것도 계약을 수행 할 수 없습니다. 컬렉션에 상태를 추가 할 수 없습니다.
  • 계약은 공급 업체가 승인합니다. 이 상태에서 아무 것도 계약을 수행 할 수 없습니다. 컬렉션에 상태를 추가 할 수 없습니다.

분명히 계약이 받아 들여지고 금액이 변경되는 상황을 피하고 싶습니다. 나는 기본적으로 해당 GUID를 기반으로 문서를 찾을 수있는 키/값 조회되는 파일 저장소 클래스를 생략 한

[EnforceNoChangesAfterDraftState] 
public class VendorContract 
{ 
public virtual Vendor Vendor { get; set; }    
public virtual decimal Amount { get; set; } 
public virtual VendorContact VendorContact { get; set; }    
public virtual string CreatedBy { get; set; } 
public virtual DateTime CreatedOn { get; set; } 
public virtual FileStore Contract { get; set; } 

public virtual IList<VendorContractStatus> ContractStatus { get; set; } 
}   

[EnforceCorrectWorkflow] 
public class VendorContractStatus 
{ 
    public virtual VendorContract VendorContract { get; set; } 
    public virtual FileStore ExecutedDocument { get; set; } 
    public virtual string Status { get; set; } 
    public virtual string Reason { get; set; } 
    public virtual string CreatedBy { get; set; } 
    public virtual DateTime CreatedOn { get; set; } 
} 

: 여기 내 클래스입니다.

VendorContractStatus는 Nhibernate에서 many-to-one으로 매핑됩니다.

그런 다음 here과 같이 맞춤 검사기를 사용하십시오. VendorContractStatus 컬렉션에 초안이 반환되면 변경 내용이 허용되지 않습니다. 또한 VendorContractStatus는 올바른 워크 플로를 따라야합니다 (보류 중 거부 된 항목을 추가 할 수 있지만 거부 또는 허용 된 항목이있는 경우 컬렉션에 다른 항목을 추가 할 수는 없습니다).

모든 소리가 괜찮습니까? 동료는 VendorContract에 "IsDraft"bool 속성을 추가하고 IsDraft가 false 인 경우 업데이트를 허용하지 말아야한다고 주장했습니다. 그런 다음 상태를 업데이트하기 위해 VendorContractStatus 내부에 메소드를 설정해야합니다. 드래프트 후에 항목이 추가되면 VendorContract의 IsDraft 속성을 false로 설정합니다.

POCOs를 더럽 히고 유효성 검사 영역에서 유지해야하는 로직을 추가하는 것처럼 느껴지므로이 규칙이 실제로는 이러한 클래스에 존재해서는 안되며 자신의 상태를 인식해서는 안됩니다. .

DDD 관점에서 더 나은 방법은 무엇입니까?

내 생각에 앞으로는 더 복잡한 규칙을 원한다면 내 길은 장기적으로 유지 관리가 가능할 것입니다. 관리자가 승인을 받기 위해 일정 금액 이상의 계약이 있다고 가정 해보십시오. IsApproved 속성을 추가하는 대신 VendorContractApproval 클래스를 사용하여 일대일 매핑을 만드는 것이 더 좋을 것이라고 생각하지만 이는 추측에 불과합니다.

머리카락이 찢어 질 수도 있지만 이것은 우리가 해본 최초의 진짜 쓸데없는 엔터프라이즈 소프트웨어 프로젝트입니다. 모든 조언을 부탁드립니다!

답변

0

발신자가 VendorContract 인스턴스를 유지하려고 시도 할 때까지 규칙이 적용되지 않는다는 사실은 버그를 더 쉽게 만들어 내고 자신의 행동이나 제약 조건을 설명하지 않기 때문에 사용하기가 더 어려워 질 수 있습니다.

단일 기능에 초점을 맞춤으로써 다른 방식을 적용하려면 거부 된 허용 된 계약에는 Amount에 대한 접근자가 있어야합니다.

anemic domain model (덜 편견적인 이름 'persistent model'으로 알려짐) 도메인 개체가 비즈니스 로직이없는 컨테이너 일 뿐인 것처럼 들릴 수 있습니다. 즉, not always a bad thing이지만 많은 비즈니스 로직이있는 시스템에서는 코드를 복제하고 너무 많은 객체에 규칙을 적용 할 위험이 있으므로 도메인 엔티티를 관리하는 규칙을 이해 (유지 및 변경)하기가 매우 어렵습니다.

+0

감사합니다. 나는 이것에 동의한다. 우리가 결정한 것은 클래스를 VendorContractDraft와 VendorContract로 분해하는 것이다. 왜냐하면 이것이 유효성 관점에서 볼 수있는 두 가지 상태이기 때문이다. 이렇게하면 별도의 유효성 검사 클래스에서 수행하는 것이 아니라 검증 로직을 사용하여 속성을 자연스럽게 마크 업할 수 있습니다. –

0

하지 마십시오. 필요한 행동을 설명하는 테스트를 작성하십시오. 데이터 모델은 모든 유스 케이스 (및 리팩토링)에 대한 테스트를 작성한 시점에 완료됩니다.

1

두 가지 사항을 고려해야합니다.

1) 계약 요청 및 시행중인 계약에 대해 동일한 객체 모델을 실제로 원하십니까? 다른 유스 케이스가 적용되지 않았습니까?

2) 동일한 개체를 사용하려는 경우 state pattern을 사용하여 현재 상태에 유효한 동작을 제어하는 ​​것이 좋습니다.

+0

이것은. 적어도 VendorContract에서 AcceptedVendorContract를 파생 시켰을 것입니다. VendorContract는 코드에서 변경되지 않습니다. AVC는 수락 된 것으로 표시된 레코드의 업데이트를 방지하는 업데이트 트리거 또는 프로그램의 SQL 사용자가 CREATE 권한 만 가진 다른 테이블에 동일한 테이블에 쓸 수 있습니다. – KeithS

+1

Keith, 가능하면 비즈니스 로직을 위해 데이터베이스를 사용하지 않을 것입니다. 테스트하기가 어려우면 레이어간에 응용 프로그램 논리를 분리 할 수 ​​있습니다. –

+0

참이므로 두 번째 옵션을 사용하십시오. 승인 된 것으로 표시되면 VendorContract는 사용자 프로그램이 수정할 권한이없는 새 테이블에 들어가고 심지어 변경할 수없는 새 개체로 검색됩니다. 이것은 NHib가 지원하는 저장소에 배치하는 것이 간단합니다. – KeithS

관련 문제