CQRS + 이벤트 소싱 아키텍처에서 Add / Create * 명령을 처리하는 방법


11

Event Sourcing과 함께 CQRS 패턴을 사용하여 첫 번째 응용 프로그램을 구현하고 싶습니다. 골재 뿌리 생성이 올바르게 처리되어야하는지 궁금합니다. 누군가 CreateItem 명령을 보낸다고 가정 해 봅시다. 어떻게 처리해야합니까? ItemCreated 이벤트를 어디에 저장해야합니까? 새로운 아이템의 첫 번째 이벤트로? 아니면 모든 항목을 집계하고 해당 이벤트 목록이 ItemCreated 이벤트로만 구성된 일종의 ItemList 엔티티가 있어야합니까?

Udi Dahan 은 집계 루트를 작성하지 말고 항상 일종의 페치 메소드를 사용 하도록 제안 합니다. 그러나 새롭고 확실하게 ID가 할당되지 않은 것을 가져올 수있는 방법. 나는 그 아이디어를 이해하고 있으며 새로운 객체는 0 개의 이벤트로 구성된 상태를 가진 객체라고 생각하는 것이 합리적입니다. 그러나 어떻게 사용해야합니까? 내 리포지토리에 고유 한 방법이 있어야합니까, getNewItem()아니면 대신 get(id)방법을 받아 들여야 Optional<ItemId>합니까?

편집 : 파고 얼마 후 배우를 사용하여 앞에서 언급 한 패턴의 흥미로운 구현 을 발견했습니다 . 작성자는 집계를 작성하는 대신 새로 작성된 UUID를 사용하여 일종의 저장소에서 집계를 검색합니다. 이 접근 방식의 단점은 일시적인 불일치 상태를 허용한다는 것입니다. 또한 delete그러한 접근 방식으로 방법을 구현할 수 있는지 궁금합니다 . 삭제 된 이벤트를 집계의 이벤트 목록에 추가하기 만 하시겠습니까?


1
Udi의 포스트 타이틀이 오도 된 것으로 보입니다. 자신처럼 IMHO는 소리 진짜 목적은 갓 만든 액세스 라우터는 항상 방법으로, 다른 장소에서 접근 할 수 있어야한다는 것입니다 그 새로운 AR가 작성 될 필요가 있다고 결정 누가 어떻게 / 왜 / 약 캡처 컨텍스트. 그 밖의 모든 것은 특정 구현 (NHibernate?)이 관리하기 쉽게 만드는 방법에 관한 것입니다.
Darien

2
참고로 언급하고있는 Udi Dahan 기사는 그의 조언이 이벤트 소싱에 적용되지 않을 수 있다고 구체적으로 설명합니다. udidahan.com/2009/06/29/dont-create-aggregate-roots/…
EZ Hart

답변:


13

Udi의 게시물에 나오는 아이디어는 얇은 공기에서 어떤 종류의 항목도 나타나지 않는다는 것입니다. 항상 (거의) 무언가, 또는 더 구체적으로, 일부 도메인 작업이있어 ​​항목이 생성되었습니다. 실제로 사이트에 등록한 방문자로부터 태어난 사용자에 대한 Udi의 예와 같습니다. 이 시점과 제한된 컨텍스트에서 방문자는 자신의 IP 주소로 검색되는 집계 루트입니다. 그런 다음이 방문자는 Register 라는 도메인 작업을 통해이 시점에서 사용자 인 새 "항목"을 만듭니다 . 이전 단계도 마찬가지입니다. 이는 또 다른 경계 컨텍스트입니다. Referrer는 AR입니다. AR은 URL로 검색되며 방문자가 태어난 BroughtVisitorWithIp 라는 도메인 작업 이 있습니다.

우디뿐만 아니라 삭제에 매우 잘 쓴다 : http://www.udidahan.com/2009/09/01/dont-delete-just-dont/ . 주요 아이디어는 아무 것도 삭제하지 않는 것입니다. 캡처하려는 도메인 작업은 항상 뒤에 있습니다. 주문이 삭제되는 것이 아니라 취소되는 것처럼. 읽어보세요. 아주 좋은 게시물입니다.

DDD, 특히 이벤트 소싱을 수행하는 두 계정의 주요 요점은 직접 CRUD 작업을 수행해서는 안된다는 것입니다. 실제로 데이터를 삽입, 업데이트 또는 삭제해야하는 상황에 처해 있고 그 뒤에 도메인 작업이없는 경우 DDD 및 이벤트 소싱이 해당 컨텍스트에 적합하지 않을 수 있습니다 . 단일 경계 컨텍스트가 하나의 원칙을 준수하는 한 원하는대로이 두 가지를 자유롭게 결합 할 수 있습니다. 이런 식으로 CRUD 스타일 경계 컨텍스트는 데이터베이스에서 일부 행을 작성할 수 있으며, 이는 다른 경계 컨텍스트에서 엔티티 및 집계 루트가되므로 AR을 검색하고 작성할 필요가 없습니다.


2
"아마도 DDD와 이벤트 소싱은 그 제한된 맥락에 적합하지 않습니다." 당신은 DDD의 요점을 올바르게 얻습니다. 사탄의 영광을 위해서만 모든 경우에 구현되어서는 안되며 불확실한 규칙으로 가득 찬 복잡한 영역을 다루어야 할 때에 만 구현해야합니다. 개인적으로 요구 사항이 논리에 의해 좌우되지 않는 합법적 인 소프트웨어를 위해했습니다.
Yegor Chumakov

2
"한정된 문맥" 에 대해이 문장 만 +1합니다 . :)
Songo

2
+1 '추가'와 '만들기'동사의 사용은 좋은 오래된 테이블 형식 데이터베이스와의 상호 작용 측면에서 여전히 도메인에 대해 생각하고 있음을 강력히 암시합니다. 도메인 / 바운드 컨텍스트를 모르면 이것이 적절한 지 말할 수 없습니다. 지속성을 무시하고 도메인에 고유 한 명령 및 이벤트 (일명 INTENTIONS 및 OUTCOMES)에 중점을 둔 후 상태를 유지하는 방법에 대해 걱정하십시오.
Matt

" '추가'와 '만들기'동사를 사용하는 것은 좋은 오래된 테이블 형식 데이터베이스와의 상호 작용 측면에서 여전히 도메인에 대해 생각하고 있음을 강력하게 암시합니다." '뭔가 추가'버튼이 큰 UI 디자인이 있다면 슬프게도 그 의도입니다. 말 그대로 새로운 것을 추가하십시오. 나는 일반적으로 당신에 동의하지만, 우리는 여기서 데이터베이스 수준을 이야기하고 있지 않습니다. 때로는 Add 또는 Create가 실제로 올바른 단어입니다.
designermonkey

1
@designermonkey UI에 해당 버튼이 있으면 실제로 그 뒤에 도메인 작업이 있습니까? 그러나 10 배 중 9 회는 해당 컨텍스트에서 복잡한 도메인 작업이 필요하지 않습니다. 그리고 순수한 CRUD 연산은 순수한 CRUD 연산이므로 처리해야합니다. 도메인 모델의 복잡성이 필요한 경우에만 사용해야합니다. 따라서 다른 디자인 원칙을 가진 다른 경계 컨텍스트.
Tuukka Haapaniemi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.