집계 경계를 설계하는 방법은 무엇입니까?


10

전자 상거래와 같은 애플리케이션을 작성하고 싶습니다.

또한 유사한 응용 프로그램에서 제품의 속성과 기능이 다를 수 있음을 알고 있습니다. 이러한 기회를 시뮬레이션하기 위해 다음 도메인 모델 엔터티를 만들었습니다.

카테고리 - "전자 제품> 옴마 터"와 같은 유형, 즉 제품 유형. 범주에는 속성 목록이 있습니다 (List <Property>).

속성 -이름, 측정 단위, 데이터 유형을 포함하는 독립 엔티티. 예를 들어 "name", "weight", "screen size"입니다. 동일한 속성이 다른 제품을 가질 수 있습니다.

제품 -속성과 관련된 이름 및 값 목록 만 포함합니다. Value는 값 필드와 속성의 필드 ID 만 포함하는 개체입니다.

예를 들어 새 제품을 추가 할 때 현재 범주와 관련된 속성 ( category.AddNewProduct (product) ) 을 포함하여 현재 범주와 관련된 모든 데이터를 알아야하기 때문에 원래이 체계에서 범주를 단일 집계처럼 만들기로 결정했습니다 . 그러나 어떤 카테고리에도 속하지 않는 새 속성을 추가해야 할 때 어떻게해야합니까? 예를 들어,이 category.AddNewProperty (property) 는 속성을 특정 범주에 추가한다고 명확하게 표시하기 때문에이 범주를 수행 할 수 없습니다 .

다음 단계에서는 속성을 별도의 집계로 분리하기로 결정했지만 간단한 엔터티가있는 목록이됩니다.

물론 PropertyAggregate와 같은 속성을 만들어 속성 ​​및 비즈니스 규칙 목록을 유지할 수는 있지만 제품을 추가 할 때 범주 내에이 속성에 속하는 속성의 전체 목록이 있어야 불변을 확인할 수 있습니다. 그러나 다른 집계에서 집계 내부의 링크를 유지하는 것은 나쁜 습관이라는 것을 알고 있습니다.

이 비즈니스 사례를 디자인 할 수있는 옵션은 무엇입니까?


카테고리, 속성 및 제품에 대한보다 완전한 예를 제공 할 수 있습니까? 전자 제품이나 컴퓨터는 범주가되고, iPhone X는 제품의 예이며, 재산은 정확히 무엇입니까? 11 인치 디스플레이?
Neil

당신은 거의 옳습니다. 몇 가지 설명을 추가했습니다
cephei

"데이터 컨테이너"관점에서만 총체적인 디자인을보고있는 것 같습니다. 또한 트랜잭션 측면, 협업 / 동시 액세스, 발생 이벤트, 상태 전이 등을 고려하여 응용 프로그램의 사용 사례에 대해 생각할 수도 있습니다.
guillaume31

답변:


7

DDD의 관점에서 Category, Product그리고 Property엔티티 : 그들은 자신의 정체성을 가진 객체에 대한 모든 대응은.

옵션 1 : 독창적 인 디자인

Category단일 집계의 루트를 만들었습니다 . 한편으로 집계는 객체가 수정 될 때 일관성을 보장해야하고 다음 중 하나 Product를 가져야 하기 때문에 이치 Properties에 맞습니다 Category.

여기에 이미지 설명을 입력하십시오

그러나 한편으로 단일 집계는 모든 개체가 해당 개체를 소유 한 루트와 관련되어 있으며 모든 외부 참조는이 집계 루트를 통해 이루어져야합니다. 이것은 다음을 의미합니다.

  • 하나의 특정 Product은 하나에 만 속합니다 Category. Category가 삭제 되면의 도 삭제됩니다 Products.
  • 특정 Property은 하나에 만 속합니다 Category. 그렇지 않으면 "TV 화면"과 "컴퓨터 모니터"가 두 가지 범주 인 경우 "TV 화면 : 크기"와 "컴퓨터 모니터 : 크기"는 서로 다른 속성이됩니다.

두 번째 요점은 당신의 이야기에 해당하지 않습니다. " 하지만 Property어떤 카테고리에 속하지 않은 새 것을 추가해야 할 때 어떻게해야합니까? " 그리고 Properties다른에서 동일한 것을 사용할 수 있는지 확실하지 않습니다 Categories.

옵션 2 : 골재 외부의 속성

Property가와 독립적으로 존재 하는 경우 Categories집계 외부에 있어야합니다. 그리고 공유 할 경우 같은 Properties사이 Categories(높이, 폭, 크기, 등등 ...에 대한 의미가된다). 이것은 분명히 사실 인 것 같습니다.

결과는 Property집합과 그 집합에 속하는 것들 사이의 링크 에 있습니다. 집합의 내부에서로 이동할 Property수는 있지만 더 이상 a Property에서 해당 값 으로 직접 이동할 수는 없습니다 . 이 탐색 제한 사항은 UML 다이어그램에 표시 될 수 있습니다.

여기에 이미지 설명을 입력하십시오

이 디자인 으로 참조 의미론 (예 : java)을 가진 List<Property>in 을 가질 수 있습니다 Category. 목록의 각 참조 Property는 저장소 의 공유 가능한 객체를 나타냅니다 .

이 디자인의 유일한 문제점은 a를 변경 Property하거나 삭제할 수 있다는 것 입니다. 집계 외부에 있으므로 집계는 불변의 일관성을 처리 할 수 ​​없습니다. 그러나 이것은 문제가되지 않습니다. 그것은 DDD 원칙과 실제 세계의 복잡성의 결과입니다. 에릭 에반스 (Eric Evans)는 " 도메인 중심 디자인 : 소프트웨어의 핵심 요소 인 태클 링 복잡성 (Tackling Complexity) "에 관한 에릭 에반스 (Eric Evans)의 인용문을 인용했다 .

AGGREGATES에 해당되는 규칙은 항상 최신 상태가 아닙니다. 이벤트 처리, 일괄 처리 또는 기타 업데이트 메커니즘을 통해 지정된 시간 내에 다른 종속성을 해결할 수 있습니다. 그러나 AGGREGATE 내에 적용된 불변은 각 거래가 완료되면 시행됩니다.

그렇습니다.를 변경하면 Property서비스가 카테고리를 확인하여 필요에 따라 업데이트되는지 확인해야합니다.

옵션 3 : 다른 집계의 범주, 속성 및 제품

Producta가 단일에 속한다 는 가정이 있는지 궁금합니다 Category.

  • 나는 종종 온라인 상점이 Product여러 곳에서 제안하는 것을 본다 Categories. 예를 들어 "노트북"범주와 "컴퓨터"범주 아래에 "노트북 브랜드 X 모델 Y"가 있고 "프린터", "스캐너"및 "팩스"범주에 "다기능 프린터 Z"가 있습니다.
  • 누군가 Product첫 번째 것을 만들고 나중에 카테고리에 할당하고 값을 채울 수 있습니까?
  • 카테고리를 나누려면 제품을 삭제 한 다음 새 카테고리 아래에서 다시 만드시겠습니까?

집계를 단순화하지 않으며 집계에 적용되는 규칙이 더 많아집니다. 그러나 시스템은 훨씬 더 미래의 증거가 될 것입니다.


대단히 감사합니다. 이것은 매우 유용한 설명입니다. 그러나 두 번째 옵션부터 시작하고 싶습니다. 누가 세 번째로 올지 알고 싶습니다. 나는이 걸릴 경우 Property의 경계를 넘어 Category집계 않는이 평균 Property자체 집계가되어 저장소를 필요가 있겠습니까? 그 다음 사실이라면 어떻게해야 합격 List<Property>Category예? 생성자를 통해? 맞을까요? 그리고 아직 생성되지 않은 PropertyID 목록을 어떻게 알 수 Category있습니까?
cephei

간단히 말해서 @zetetic : 예, 독립적 인 Property 저장소가 필요합니다. 기존 속성 목록을 카테고리의 팩토리로 전달하거나 빈 카테고리를 작성하고 addProperty 메소드로 목록을 채 웁니다. 답장 : "필수"및 "선택"속성을 원한다고 가정하고 필수 특성은 카테고리에 따라 다릅니다. 이걸 어떻게 처리하겠습니까?
Christophe

귀하의 질문에 대답하는 첫 번째 생각은 내가 특별한 엔티티를 만들 수 Feature있으며 그것은 오직에 속해 있다는 것 Product입니다. 이 엔티티는 검색에 참여하지 않습니다. 당신은 무엇을 말합니까?
cephei

@zetetic 왜 안돼! Values가 현재 제품에있는 것처럼 값을 그대로 두 었으며 기능을 범주에 연결했습니다. 카테고리에는 n 개의 피쳐 (집계의 일부)가 있으며 속성은 m 개의 피쳐를 정의하지만 링크는 카테고리-> 피처를 통해 이동합니다. 그런 다음 다 대다 관계를보다 관리하기 쉬운 요소로 분해하여 집계 경계를 명확하게합니다. 마지막으로 리포지토리 주입에 대해 : ID로 다른 집계를 참조하는 경우 필요하지 않습니다 ( infoit.com/articles/article.aspx?p=2020371&seqNum=4 참조 )
Christophe

5

내가 알듯이 두 가지 방법 중 하나로이 문제를 해결할 수 있습니다.

카테고리는 특별한 유형의 제품입니다

이는 데이터베이스의 특정 제품에 대해 동일한 테이블 제품을 가리키는 외래 키를 포함한다는 것을 의미합니다. 제품은 외래 키가 해당 제품의 id와 동일한 제품이없는 경우에만 제품입니다. 다시 말해, 제품이 없으면 제품입니다.

이것은 일을 조금 단순화합니다. 제품 대 속성은 일대 다 관계를 가지므로 카테고리도 제품이므로 일대 다 관계를 갖습니다. 프로그램에서 제품에 속성을 추가하는 것만 큼 범주에 속성을 추가하는 것이 쉽습니다. 모든 속성을로드한다는 것은 제품의 속성을 관련 범주 제품의 속성과 결합하지 않고 상위가없는 범주 제품에 도달 할 때까지 계속하는 것을 의미합니다.

전자 상거래 응용 프로그램에서 이러한 차이점을 확인해야하지만 카테고리의 제품을로드 할 가능성이있는 경우 카테고리 또는 제품을 처리하는지 여부를 아는 것은 성능 손실이 아닙니다. 또한 각 제품 (범주)이 많은 추가 작업없이 하위 제품 목록을 열 수 있으므로 제품 수준에 따라 트리 방식으로 검색하는 데 적합합니다.

이것의 단점은 물론 범주에 맞지 않는 제품에 존재하는 추가 정보는 제품에 사용되지 않는 필드를 어색하게 만듭니다. 이 솔루션은 응용 프로그램에서보다 유연하지만 직관적이지 않습니다.

다 대다 관계

제품은 더 이상 속성과 복합적인 관계에 있지 않습니다. 제품 테이블과 속성 테이블 둘 다의 외래 키를 사용하여 ProductProperty 테이블을 만듭니다. 마찬가지로, 속성 테이블과 다 대다 관계가있는 범주 테이블과 범주 테이블과 속성 테이블의 외래 키가있는 CategoryProperty 테이블이 있습니다.

제품 자체는 범주와 다 대일 관계를 가지므로, 형식화 된 Select 문을 통해 제품 및 범주와 관련된 고유 속성 목록을 본질적으로 만들 수 있습니다.

데이터베이스의 관점에서 볼 때 이것은 명확하고 유연합니다. 쿼리가 제대로 수행되면 응용 프로그램이 CategoryProperty 또는 ProductProperty를 직접 처리하지 않고도 대부분 수행 할 수 있습니다. 그러나 카테고리 나 제품을 재산 소유자로 취급해서는 안됩니다. 프로그램 내에서 고유 한 엔티티 여야합니다. 이는 또한 해당 속성의 관리가 속성 자체를 생성 한 다음 두 가지 단계로 카테고리 또는 제품과 연결하는 문제라는 것을 의미합니다. 확실히 첫 번째 솔루션보다 더 많은 작업이 필요하지만 결코 더 어려운 것은 아닙니다.

이 외에도, 특정 제품 / 카테고리의 모든 관련 속성을 안전하게 제거 할 수있는 첫 번째 솔루션과 달리 다른 속성이 해당 속성을 사용중인 경우 카테고리 또는 제품을 삭제하면 추가 검사를 수행해야합니다. .

결론

전문적인 맥락에서, 나는 다 대다 접근 방식을 사용하여 제품 및 제품에서 추가 마일 및 거리 범주를 사용하려고합니다. 데이터가 겹칠 가능성은 없으며 어떤 의미에서는이 세 가지를 각각 고유 한 엔티티로 추론하기가 더 쉽습니다. 그러나 더 간단한 응용 프로그램을 작성할 수 있기 때문에 첫 번째 솔루션이 나쁜 방법은 아닙니다. 한 솔루션에서 다른 솔루션으로 궁극적으로 전환해야 할 필요가 있다고 생각되면 아마도 두 번째 솔루션을 선택하는 것이 최선의 이익 일 것입니다.

행운을 빕니다!


상세하고 흥미로운 답변에 감사드립니다! 두 번째 경우에서 설명했듯이 이미 모델링 한 데이터베이스 수준에서이 패턴을 엔터티 속성 값이라고하지만 코드 수준, 즉 집계 정의에 갇혀 있습니다. 대부분의 경우 이러한 모든 엔티티가 함께 사용됩니다. 하나의 집계로 결합하는 것이 가능하지만 의미 상 집계에서 벗어나는 디렉토리 채우기와 같은 경우가 있습니다.
cephei
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.