문제

이것은 실용적인 도메인 중심 디자인 질문입니다.

개념적으로, 나는 하나를 정의 할 때까지 집계 뿌리를 얻는다고 생각합니다.

직원 기업이 있는데,이 엔티티는 집계 루트로 표시되었습니다. 사업에서 약간 직원은 직장 관련 위반을 그들에게 로그인 할 수 있습니다.

직원 -----*위반

모든 직원이 이에 적용되는 것은 아니기 때문에 위반이 직원 집계의 일부가 아니라고 생각합니다.

따라서 직원 및 관련 위반과 함께 일하고 싶을 때는이 두 가지 서비스에서 두 가지 별도의 저장소 상호 작용입니까?

마지막으로 위반을 추가 할 때 직원 실체에 해당 방법이 있습니까? 도와 주셔서 감사합니다!

도움이 되었습니까?

해결책

더 많은 연구를 한 후, 나는 내 질문에 대한 답이 있다고 생각합니다.

Paul Stovell은 DDD 메시지 보드. "직원"으로 "고객"을 대체하고 "위반"을 위해 "주문"을 대체하면 아이디어를 얻습니다.

고객 참조 주문이 반드시 주문이 고객 집계 루트 내에 있다는 것을 의미하는 것은 아닙니다. 고객의 주소는 지루 할 수도 있지만 주문은 독립적 일 수 있습니다 (예 : 고객이 누구인지에 관계없이 모든 새로운 주문을 처리하는 서비스가있을 수 있습니다. 고객-> 주문 이이 시나리오에서는 의미가 없습니다).

도메인 관점에서, 해당 참조의 유효성에 의문을 제기 할 수도 있습니다 (고객은 주문 목록을 참조합니다). 실제로 얼마나 자주 필요한지 모두 고객 주문? 일부 시스템에서는 의미가 있지만 다른 시스템에서는 한 고객이 많은 주문을 할 수 있습니다. 날짜 범위간에 고객에 대한 주문 또는 아직 처리되지 않은 고객에 대한 주문 또는 지불되지 않은 주문 등을 원할 가능성이 있습니다. 당신이 필요로하는 시나리오는 모두 비교적 드문 일 수 있습니다. 그러나 주문을 처리 할 때 고객 정보를 원할 가능성이 훨씬 높습니다. 그래서 코드에서 Order.Customer.Name 유용하지만 Customer.Orders[0].LineItem.SKU - 아마도 그렇게 유용하지 않을 것입니다. 물론, 그것은 당신의 비즈니스 도메인에 전적으로 달려 있습니다.

다시 말해, 고객 업데이트는 주문 업데이트와 관련이 없습니다. 내 경우에 명령 또는 위반은 고객/직원과 독립적으로 다루어 질 수 있습니다.

위반에 세부 사항이있는 경우 위반 라인을 변경하면 위반에 영향을 줄 수 있기 때문에 위반 및 위반 라인이 동일한 집계의 일부가됩니다.

편집 ** 내 도메인의 주름은 위반에 행동이 없다는 것입니다. 그들은 기본적으로 일어난 사건의 기록입니다. 아직 미치는 영향에 대해 확실하지 않습니다.

다른 팁

Eric Evan은 그의 저서에서 말하며 도메인 중심 디자인 : 소프트웨어의 핵심 복잡성을 다루고 있습니다.,

집계는 우리가 단위로 취급하는 관련 객체의 클러스터입니다. 데이터 변경을 위해.

여기에는 두 가지 중요한 점이 있습니다.

  1. 이 물체는 "단위"로 취급되어야합니다.
  2. "데이터 변경"의 목적으로.

나는 당신의 시나리오, 직원 및 위반이 반드시 단위 일 필요는 없지만, 순서와 순서의 예에서는 단일 단위의 일부입니다.

Agggregate 경계를 모델링 할 때 중요한 또 다른 것은 집계에 불변량이 있는지 여부입니다. 불변은 "전체"집계 내에서 유효 해야하는 비즈니스 규칙입니다. 예를 들어, 순서 및 순서 예제와 관련하여, 주문의 총 비용이 사전 정의 된 금액보다 적어야하는 변하지 않을 수 있습니다. 이 경우 주문에 주문시를 추가 할 때 마다이 불변량은 주문이 유효한지 확인해야합니다. 그러나 귀하의 문제에서는 직원과 위반과 같은 귀하의 단체 간의 불변량이 없습니다.

너무 짧은 대답 :

나는 직원과 위반이 각각 2 개의 별도의 골재에 속한다고 생각합니다. 이러한 각 엔티티는 또한 고유 한 집계 뿌리입니다. 따라서 2 개의 리포지토리가 필요합니다.

또한 위반에서 직원에 이르기까지 단방향 협회가 있어야한다고 생각합니다. 이런 식으로, 각 위반 대상은 그것이 속한 사람을 알고 있습니다. 그러나 특정 직원에 대한 모든 위반 목록을 얻으려면 위반 예비를 요청할 수 있습니다.

var list = repository.FindAllViolationsByEmployee(someEmployee);

귀하는 직원 실체와 위반이 있으며 각 위반에는 행동 자체가 없다고 말합니다. 내가 위에서 읽을 수있는 것에서, 당신은 두 개의 집계 뿌리를 가질 수있는 것 같습니다.

  • 직원
  • EmployeeViolations (IT IT EmployeeViolationCard 또는 EmployeeViolationRecords 호출)

Employeeviolations는 동일한 직원 ID에 의해 식별되며 위반 개체 모음을 보유하고 있습니다. 직원에 대한 행동을 얻고 위반은 이런 식으로 분리되며 행동없이 위반 엔터티를 얻지 못합니다.

위반이 엔티티 또는 가치 객체인지 여부는 속성에 따라 결정해야합니다.

나는 일반적으로 이것에 대해 mosh에 동의합니다. 그러나 비즈니스 관점에서 거래의 개념을 명심하십시오. 따라서 실제로 "데이터 변경의 목적"은 "거래 목적을 위해"를 의미합니다.

리포지토리는 도메인 모델의 뷰입니다. 도메인 환경에서 이러한 "보기"는 실제로 비즈니스 기능 또는 기능 - 거래를 지원하거나 나타냅니다. 예를 들어, 직원은 하나 이상의 위반을 가질 수 있으며, 그렇다면 어느 시점에서 거래의 측면입니다. 사용 사례를 고려하십시오.

시나리오 : "직원은 직장을 위반하는 행위를 저지른다." 이것은 발생한 비즈니스 이벤트 유형 (즉, 거래 또는 더 큰 분산 거래의 일부)입니다. 루트 영향을받는 도메인 객체는 실제로 하나 이상의 관점에서 볼 수 있으므로 혼란스러운 이유입니다. 그러나 기억해야 할 것은 비즈니스 프로세스가 가능한 한 정확하게 모델을 모델링하기를 원하기 때문에 비즈니스 거래와 관련된 행동입니다. 관계 측면에서 관계형 데이터베이스와 마찬가지로 개념적 도메인 모델은 실제로 이것을 이미 나타내야합니다 (즉, 연관성).

직원 <----------------------------------------------------------------------

따라서이 사용 사례의 경우 위반을 다루는 거래이며 루트 또는 "기본"엔티티가 위반이라고 말하는 것이 공평합니다. 그렇다면 특정 비즈니스 활동 또는 비즈니스 프로세스에 대해 참조 할 총체적인 근본이 될 것입니다. 그러나 다른 활동이나 프로세스의 경우 "새로운 직원 프로세스"와 같은 직원 집계 루트를 가질 수 없다고 말하는 것은 아닙니다. 주의를 기울이면 주기적 참조의 부정적인 영향이 없거나 도메인 모델을 여러 가지 방법으로 통과 할 수 없어야합니다. 그러나 나는 이것을 통치하는 것이 당신의 비즈니스 도메인의 컨트롤러 조각에 대해 생각하고 처리해야한다고 경고 할 것입니다.

제쳐두 : 패턴 (예 : MVC)의 관점에서 생각하는 저장소는 뷰이며 도메인 객체는 모델이므로 일부 형태의 컨트롤러 패턴을 사용해야합니다. 일반적으로 컨트롤러는 저장소의 구체적인 구현 및 액세스를 선언합니다 (집계 루트 모음).

데이터 액세스 세계에서 ...

LINQ-to-SQL을 예로 사용하면 Datacontext는 고객 및 주문 엔티티의보기를 노출시키는 컨트롤러입니다. 보기는 비결정, 프레임 워크 지향 테이블 유형 (저장소와 거친)입니다. 보기는 부모 컨트롤러에 대한 참조를 유지하며 종종 컨트롤러를 통해 뷰가 구체화되는 방법/시기를 제어합니다. 따라서 컨트롤러는 매핑, 번역, 객체 수화 등을 관리하는 제공자입니다. 모델은 데이터 pocos입니다. 거의 전형적인 MVC 패턴입니다.

n/hibernate를 예로 사용하면 세션은 세션을 통해 고객 및 주문 엔티티의 관점을 노출시키는 컨트롤러입니다. ).목록()

비즈니스 논리 세계에서 ...

Customer { /*...*/ }

Employee { /*...*/ }

Repository<T> : IRepository<T>
              , IEnumerable<T>
              //, IQueryable<T>, IQueryProvider //optional

{ /**/ }

BusinessController {
 Repository<Customer>  Customers { get{ /*...*/ }} //aggregate root
 Repository<Order> Orders { get{ /*...*/ }} // aggregate root
}

간단히 말해서, 비즈니스 프로세스와 거래가 가이드가되도록하고, 프로세스/활동이 구현되거나 재현 될 때 비즈니스 인프라가 자연스럽게 진화하도록하십시오. 또한 전통적인 블랙 박스 디자인보다 합성 가능성을 선호하십시오. 서비스 지향 또는 클라우드 컴퓨팅에 도달하면 기뻐할 것입니다. :)

나는 결론이 무엇인지 궁금했다.

'위반'은 루트 엔티티가됩니다. '위반'은 '직원'루트 엔티티가 참조합니다. IE 위반 저장소 <-> 직원 저장소

그러나 당신은 행동이 없기 때문에 위반을 뿌리 실체로 만드는 것에 대해 위반에 대해 위반되었습니다.

그러나 '행동'은 루트 엔티티 자격을 갖춘 기준입니까? 나는 그렇게 생각하지 않습니다.

여기에서 이해를 테스트하고 순서로 돌아 가기위한 약간의 직교 질문 ... 순서 예, 순서를 직접 조사하려는 분석 모듈이있을 수 있습니다. 즉, 특정 제품에 대한 모든 순서 또는 모든 주문 항목이 주어진 값 등은 그런 식으로 많은 usecase를 가지고 있으며 "집합 뿌리"를 극단적으로 주행 할 수 있습니다.

때에 따라 다르지. VIOATION의 변경/추가/삭제가 직원의 일부를 변경합니까? 예를 들어 직원에 대한 지난 3 년 이내에 위반 카운트 또는 위반 수를 저장하고 있습니까?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top