집합체의 디자인 트레이드 오프를 이해하는 것이 중요합니다. 집계는 도메인 모델을 독립 공간으로 분할하기 때문에 관련없는 모델 부분을 동시에 수정할 수 있습니다. 그러나 변경 지점에있는 여러 집계 에 걸쳐있는 비즈니스 규칙을 적용 할 수있는 능력을 잃게됩니다.
이것이 의미하는 바는이 두 가지의 비즈니스 가치를 명확하게 이해해야한다는 것입니다. 매우 자주 변경되지 않는 엔티티의 경우, 동시 변경보다 엄격한 집행을 선호 할 수 있습니다. 데이터가 자주 변경되는 경우 더 많은 격리를 선호하게 될 것입니다.
실제로 "격리"란 비즈니스가 "충돌하는"편집으로 인해 모델이 만족스럽지 않은 상태에있는 경우를 완화 할 수 있는지 평가하는 것을 의미합니다.
이 합계를 사용하여 사용자 유형을 변경할 수 있지만 해당 계정 (불변 중 하나)에 사용할 수있는 유형 만 가능합니다.
이와 같은 불변 식이기 때문에 중요한 질문은 "여기의 실패의 비즈니스 비용은 무엇입니까?"입니다.
User
과 Account
이 개별 집계 인 경우 계정이 해당 유형에 대한 지원을 중단하는 것과 동시에 사용자가 "유형"에 할당된다는 문제가 있습니다. 그러면 "불변"에 대한 위반이 있었음을 (변경 이후에) 발견하게되고, 수정을 적용하는 데 드는 비용은 얼마입니까?
Account
이 비교적 안정적인 경우 (해당되는 것처럼 보임) 사용자 유형을 계정에 허용 된 캐시 목록과 비교하면 이러한 오류의 대부분을 완화 할 수 있습니다. 이 캐시는 사용자가 변경 될 때 또는 편집을 지원하는 UI에서 평가 될 수 있습니다. 동시 편집을 손상시키지 않으면 서 오류율을 줄이거 나 없앨 수 있습니다.
내 도메인 모델은 UserAccount라고해야하며 Account, User 및 UserType 엔터티로 구성되어야합니다. 여기서 Account는 집계 루트입니다.
나는 여기에서 음모를 잃어 버렸다고 생각합니다. "도메인 모델"은 실제로는 명명 된 것이 아니며 단지 집계의 모음입니다. 당신은 사용자 및 UserTypes를 포함하는 계정 집계를 원한다면
는, 당신은 아마 그것을이 디자인은 사용자에 대한 모든 변경 사항은 계정 집계를 통해 액세스 할 필요가 있음을 의미한다
Account : Aggregate {
accountId : Id<Account>,
name : AccountName,
users : List<User>,
usertypes : List<UserType>
}
같은 모델, 그리고 것 사용자가 둘 이상의 계정에 속해 있지 않으며 다른 집계가 사용자를 직접 참조 할 수 없다는 점입니다 (계정 집합과 직접 협상해야 함). 내가 저장소에서 UserAccount를 가져올 때
Account::SetUserType(UserHint hint, UserType userTypeId){
if(! usertypes.Contains(userTypeId)) {
throw new AccountInvariantViolationException();
}
User u = findUser(users, hint);
...
}
, 내가 필요한 모든 테이블 (또는 엔티티 데이터 개체)를 가져오고 집계를 매핑하고, 전체를 반환합니다.
는 네, 정확히 맞아 - 우리가 일반적으로 느슨하게 결합 된 작은 집계보다는 하나의 큰 집계를 선호하는 또 다른 이유입니다.
계정 집합과 계정 유형 (accountUser 엔터티)에 살고있는 계정과 사용자 간의 관계 만 있고 나머지 사용자 정보는 별도의 사용자 집합체로 유지해야합니까? 모델은 문제의 일부 종류 일 수
-이 경우는, 계정 집계는 것 아마
Account : Aggregate {
accountId : Id<Account>,
name : AccountName,
users : Map<Id<User>,UserType>
usertypes : List<UserType>
}
같은이 디자인은 누군가가 UserType을 제거하려고 할 경우 예외를 던질 수 있습니다 보인다 일부 사용자가 현재 해당 유형의 계정 일 때 그러나 여기에 설명 된 사용자 유형이 실제로 독립적 인 사용자 집합체의 상태와 일치하는지 또는 식별 된 사용자가 있는지 여부를 확인할 수는 없습니다 (이러한 경우에 대한 탐지 및 완화에 의존 할 것입니다) .
더 좋습니까? 보다 나쁜? 실제로 다루고있는 실제 문제에 대한 철저한 이해 없이는 말할 수 없습니다 (ddd 장난감 문제를 이해하는 것은 정말로 어렵습니다).
원칙은 비즈니스 불변량이 항상 유지되어야하며 (나중에 조정이 허용되는 것과는 반대되는) 비즈니스 불변량을 파악한 다음 불변성을 충족시키기 위해 일관성을 유지해야하는 모든 상태를 그룹화하는 것입니다.
그러나 계정에 수백 또는 수천 명의 사용자가있을 수 있다면 어떻게 될까요?골재에 대한 당신의 비전은 무엇입니까?
동일한 제약 조건 : 사용자 유형의 허용 범위를 담당하는 일부 집계가 있다고 가정합니다. 합계가 너무 커서 합리적인 방법으로 관리 할 수없고 비즈니스를 완화 할 수 없다면 아마도 "저장소"추상화가 손상되고 유효성 검사 규칙을 적용하여 데이터베이스 자체에 누출 될 수 있습니다.
원본 OO 베스트 프랙티스의 뿌리에서 가져온 DDD의 장점은 모델이 실제이며 지속성 저장소가 환경적인 세부 사항이라는 것입니다. 그러나 프로세스가 수명주기를 갖고 경쟁하는 소비자가있는 세계에서 실용적인 시각으로 바라 보았습니다 ... 비즈니스의 진실을 나타내는 지속 저장소입니다.
이전에 비슷한 내용에 대해 이야기했지만 계정과 사용자 간의 관계 만이 계정 집합과 사용자 유형 ('AccountUser' 엔티티)에 살고 나머지 사용자 정보는 실시간으로 살아야합니다 별도의 '사용자'집계에? – plalx
'User' aggregate 자체가 결정을 내리기 위해 자신의 타입에 의존 할 필요가없는 한, 경합을 최소화하면서 규칙을 강하게 일관되게 유지하는 방법이 될 수 있습니다. – plalx
코드 예에서 사용자 목록과 함께 계정 집계를 만들었습니다. 하지만 계정에 수백 또는 수천 명의 사용자가있을 수 있다면 어떨까요? 골재에 대한 당신의 비전은 무엇입니까? – Robert