2011-08-10 5 views
1

도메인 모델을 사용하려고하는 응용 프로그램에서 작업하고 있습니다. 아이디어는 비즈니스 모델을 도메인 모델의 개체 안에 유지하는 것입니다. 이제는 관련 객체를 구독하는 객체가 변경 사항에 대응하기 위해 많은 작업을 수행합니다. 이 작업은 PropertyChanged 및 CollectionChanged를 통해 수행됩니다. 다음을 제외하고이 작업은 정상적으로 작동합니다.도메인 모델이 이벤트를 사용하여 일관성을 유지해야합니까?

복잡한 작업 : 많은 변경 사항이 그룹으로 처리되어야하며 개별 속성/모음이 변경되지 않아야합니다. I/how는 어떻게해야합니까?

지속성 : 지속성을 위해 NHibernate를 사용하며 클래스의 public 속성 설정 자도 사용합니다. Hibernate가이 속성에 부딪 힐 때 많은 bussiness 논리가 수행된다 (불필요한 것처럼 보인다). NHibernate에 사용자 정의 setter를 사용해야합니까?

도메인 모델에서 모든 로직을 밀어 넣으면 도메인 모델이 다소 복잡해집니다. 어떤 아이디어 ???

enter image description here

이 가입하여 서로 반응하는 다음은 프로젝트 내 컨테이너와 개체를 볼 수 있습니다

여기에 (내가 사용하는 엉터리 공구 죄송합니다)에 '샘플'문제입니다. 이제 네트워크 변경은 NetworkEditor를 통해 이루어 지지만이 편집기는 NetworkData에 대한 지식이 없습니다. 이 데이터는 때로는 다른 어셈블리에서 정의 될 수도 있습니다. 흐름은 사용자 -> NetworkEditor-> Network-> NetworkData 및 관심있는 모든 다른 개체에서 시작됩니다. 이것은 규모에 맞지 않는 것 같습니다.

답변

2

이제 DDD와 PropertyChanged/CollactionChanged 이벤트의 조합이 가장 좋은 아이디어 일 수 있습니다. 문제는 이러한 이벤트를 기반으로 로직을 구성하면 하나의 PropertyChanged가 다른 이벤트로 연결되고 나머지 이벤트는 곧 느슨한 컨트롤이되므로 복잡성을 관리하는 것이 매우 어렵다는 것입니다.

ProportyChanged 이벤트와 DDD가 정확히 맞지 않는 또 다른 이유는 DDD에서 모든 비즈니스 작업이 가능한 한 명시 적이어야한다는 것입니다. DDD는 기술적 인 요소를 비즈니스 세계에 도입해야한다는 것을 명심하십시오. 그리고 PropertyChanged/CollectionChanged를 기반으로하는 것은 매우 명확하지 않습니다.

DDD의 주요 목표는 집계 일관성을 유지하는 것입니다. 즉 집계를 호출하는 모든 연산이 유효하고 일관성이 있어야합니다 (물론 연산이 성공하는 경우).

'건물'거래에 대해 걱정할 필요가없는 모델을 만들면 집계에 대한 작업은 거래 자체 여야합니다.

모델이 어떻게 생겼는지는 모르겠지만 집계 트리에서 책임을 한 단계 위로 이동하면 PropertyChanged 이벤트에 의존하는 대신 프로세스에 논리 엔터티를 추가 할 가능성이 있습니다.

예 :

당신이 상태 때마다 지불 변경, 당신은 고객 주문의 전체 균형을 다시 계산하려면 결제시의 컬렉션을 있다고 가정 할 수 있습니다.대신 지불 수집에 대한 변경 사항을 가입하고 수집 변경, 당신은 같은 것을 할 수있는 경우에 고객에 대한 메소드를 호출 :

public class CustomerOrder 
    { 
     public List<Payment> Payments { get; } 
     public Balance BalanceForOrder { get; } 

     public void SetPaymentAsReceived(Guid paymentId) 
     { 
      Payments.First(p => p.PaymentId == paymentId).Status = PaymentStatus.Received; 
      RecalculateBalance(); 
     } 
    } 

당신은 우리가 하나의 질서의 균형과하지의 균형을 다시 계산 것을 눈치 챘을 수도 전체 고객 - 대부분의 경우 고객이 다른 집계에 속하므로 확인이 필요하며 필요한 경우 잔액을 간단히 쿼리 할 수 ​​있습니다. 이것은 정확하게 '집계'내에서만 일관성을 보여주는 부분입니다. 우리는이 시점에서 다른 집계를 신경 쓰지 않습니다. 단일 주문 만 처리합니다. 요구 사항에 맞지 않는 경우 도메인이 잘못 모델링됩니다.

요점은 DDD에는 모든 시나리오에 대해 좋은 모델이 하나도 없다는 것입니다. 비즈니스 성공 방법을 이해해야합니다.

위의 예를 살펴보면 거래를 '구성'할 필요가 없음을 알 수 있습니다. 전체 거래는 SetPaymentAsReceived 방법에 있습니다. 대부분의 경우, 하나의 사용자 조치는 집계가있는 엔티티에서 하나의 특정 메소드로 연결되어야합니다.이 메소드는 비즈니스 조작과 명시 적으로 관련됩니다 (물론이 메소드는 다른 메소드를 호출 할 수도 있음).

DDD의 이벤트에는 도메인 이벤트 개념이 있지만 PropertyChanged/CollectionChanged 기술 이벤트와 직접 관련이 없습니다. 도메인 이벤트는 집계에 의해 완료된 비즈니스 운영 (트랜잭션)을 나타냅니다.

Overal는 도메인 모델의 모든 논리를 밀어 것은 복잡한 비즈니스 로직과 시나리오에 사용하도록되어 같이 수행 물론

오히려 복잡 도메인 모델을 만드는 것 같습니다. 그러나 도메인을 올바르게 모델링 한 경우 이러한 복잡성을 쉽게 관리하고 제어 할 수 있으며 이는 DDD의 장점 중 하나입니다.

추가 예를 제공 한 후 : 프로젝트라는 집계 루트를 만드는 방법에 대해

가 좋아, 무엇을 - 당신이 저장소에서 집계 루트를 빌드 할 때, 당신은 NetworkData 그것을 채울 수 있으며, 작업은 다음과 같습니다

public class Project 
    { 
     protected List<Network> networks; 
     protected List<NetworkData> networkDatas; 

     public void Mutate(string someKindOfNetworkId, object someParam) 
     { 
      var network = networks.First(n => n.Id == someKindOfNetworkId); 
      var someResult = network.DoSomething(someParam); 

      networkDatas.Where(d => d.NetworkId == someKindOfNetworkId) 
       .ToList() 
       .ForEach(d => d.DoSomething(someResult, someParam)); 
     } 
    } 

NetworkEditor는 NetworkId를 사용하는 프로젝트가 아니라 네트워크에서 직접 작동하지 않습니다.

+0

스폿이 켜져 있습니다. DDD 엔티티는 등록 정보 및 수집 변경 사항을 합법적으로보고 할 수 있지만 프리젠 테이션 코드와 같은 외부 옵저버 만이 도메인 로직을 목적으로하지 않습니다. – jnm2

관련 문제