더 복잡한 누적 루트 구조 및 이벤트 소싱에 문제가 있습니다. 당신이 볼 수 있듯이이벤트 소싱 - AR에서 entites로 이벤트 전달
class AggregateRoot{
Entity entity1;
Entity entity2;
//this is returned to service layer to be persisted to db in event stream
AggregateRootUpdatedState execCommand(int command){
entity1 = new Entity();
EntityUpdatedStateEvent event1 = this.entity1.changeState(command);
EntityUpdatedStateEvent event2 = null;
if(entity1.state==1) { //since we already set sub entity - we can check this
entity2 = new Entity();
event2 = this.entity2.changeState(command);
}
AggregateRootUpdatedState parentEvent = new AggregateRootUpdatedState(event1, event2);
//when(parentEvent); //??? WE ALREADY CHANGED STATE IN TWO LINES ABOVE
return parentEvent;
}
void when(AggregateRootUpdatedState event){ //needed for re-hydrating the event state
entity1 = new Entity();
entity1.when(event.event1);
if(event.event2!=null) {
entity2 = new Entity();
entity2.when(event.event2);
}
}
}
class Entity{
int state;
EntityUpdatedStateEvent changeState(int state){
EntityUpdatedStateEvent event = new EntityUpdatedStateEvent(state);
when(event);
return event;
}
void when(EntityUpdatedStateEvent event){
this.state = event.state;
}
}
class EntityUpdatedStateEvent{
int state;
EntityUpdatedStateEvent(int state) {
this.state = state;
}
}
class AggregateRootUpdatedState{
EntityUpdatedStateEvent event1; //here we are nesting events AR->Entity
EntityUpdatedStateEvent event2;
AggregateRootUpdatedState(EntityUpdatedStateEvent event1, EntityUpdatedStateEvent event2) {
this.event1 = event1;
this.event2 = event2;
}
}
는, 하나의 집계 루트이 하위 기관 entity1
및 entity2
을 가지고 AggregateRoot
이 : 나는이 코드 조각이 있다고 할 수 있습니다. AR이 명령 (이 경우 단순한 int command
)을 받으면 상태를 수정하기 위해 하위 엔티티의 일부 메소드를 호출해야합니다. 이에 대한 반작용으로 when
메서드를 호출하여 엔티티 내부에 자동으로 적용되는 EntityUpdatedStateEvent
을 발생시킵니다. 이 시점에 이벤트를 적용하면 엔티티가 반환 될 때 루트의 집계가 올바른 상태로 유지되며 집계 루트에서 비교 테스트 if(entity1.state==1)
을 수행 할 수 있습니다. 이 테스트에 따라 다른 엔티티 상태도 업데이트합니다. 두 이벤트 모두 이벤트 저장 영역에 보존되는 AggregateRootUpdatedState
이벤트로 구성됩니다.
지금 내 질문은 - AR에서 나는 처음으로 메서드를 호출하지 않습니다. AggregateRootUpdatedState
(AR 재 수화에만 해당)이 발생합니다. AR 주소도 when
메서드를 호출하여 수정해야한다는 것을 알았 기 때문에 올바른 접근 방법입니까?
이벤트를 AR 계층 구조로 전달하는 다른 방법이 있습니까? 1 예는 내 진짜 문제에 더 비현실적 이었기 때문에
UPDATE
class AggregateRoot{
List<SubEntityLevel1> subEntityLevel1s;
int rootNum;
void command(int x){
rootNum = x*x;
for(int i=0; i<x; i++){
SubEntityLevel1 subEntityLevel1 = new SubEntityLevel1();
subEntityLevel1.modify1(i, rootNum);
subEntityLevel1s.add(subEntityLevel1);
}
}
void when(AggregateRootModifiedEvent event){
//HOW TO REFACTOR METHOD ABOVE TO EVENT?
}
}
class SubEntityLevel1{
int id;
List<SubEntityLevel2> subEntityLevel2s;
int sum = 0;
void modify1(int id, int rootNum){
//HOW TO MAKE EVENT FROM THIS AND THEN APPLY IN WHEN() METHOD?
this.id = id;
this.sum = rootNum;
for(int i=0; i<id; i++){
if(subEntityLevel2s.stream().noneMatch(se2 -> "0".equals(se2.id))) {
SubEntityLevel2 subEntityLevel2 = new SubEntityLevel2();
subEntityLevel2.modify2(i);
subEntityLevel2s.add(subEntityLevel2);
sum++;
}
}
}
void when(SubEntityLevel1Modified event){
this.id = event.id;
this.sum = event.sum;
for(SubEntityLevel2Modified subEvent : event.subEntity2Events){
when(subEvent);
}
}
void when(SubEntityLevel2Modified event){
SubEntityLevel2 subEntityLevel2 = new SubEntityLevel2();
subEntityLevel2.when(event);
subEntityLevel2s.add(subEntityLevel2);
}
void when(SubEntityLevel2Created event){
//??????
}
}
class SubEntityLevel2{
String id;
SubEntityLevel2Modified modify2(int x){
SubEntityLevel2Modified event = new SubEntityLevel2Modified(String.valueOf(x));
when(event);
return event;
}
void when(SubEntityLevel2Modified event){
this.id = event.id;
}
}
//----- EVENTS
class AggregateRootModifiedEvent{
int rootNum;
List<SubEntityLevel1Modified> subEntity1Events;
public AggregateRootModifiedEvent(int rootNum, List<SubEntityLevel1Modified> subEntity1Events) {
this.rootNum = rootNum;
this.subEntity1Events = subEntity1Events;
}
}
class SubEntityLevel1Modified{
int id;
List<SubEntityLevel2Modified> subEntity2Events;
int sum;
public SubEntityLevel1Modified(int id, List<SubEntityLevel2Modified> subEntity2Events, int sum) {
this.id = id;
this.subEntity2Events = subEntity2Events;
this.sum = sum;
}
}
class SubEntityLevel2Created{}
class SubEntityLevel2Modified{
String id;
SubEntityLevel2Modified(String id){
this.id = id;
}
}
, 나는 실제로 그들과 몇 가지 추가의 모두에서 목록의 중첩과 3 개 수준이이 새로운 하나를 업데이트 질문 논리. 나는 기본적으로이 메소드 (예 : SubEntityLevel1
, modify1
의 메소드)를 리팩터링하여 이벤트 소싱 (먼저 이벤트를 작성한 후 적용)에 어려움을 겪고있다. 나는 몇 가지 해결책을 가지고 있지만, 장소에 소싱 이벤트가없는 것보다 훨씬 더 복잡한 것처럼
2
OK UPDATE, ... 두 이벤트는 다음 AggregateRootUpdatedState로 구성되어
class AggregateRoot{
List<SubEntityLevel1> subEntityLevel1s = new ArrayList<>();
int rootNum;
List<Object> command(int x){
List<Object> tempEvents = new ArrayList<>();
//rootNum = x*x;
int tempRootNum = x*x;
for(int i=0; i<x; i++){
SubEntityLevel1 subEntityLevel1 = new SubEntityLevel1();
List<Object> subEvents = subEntityLevel1.modify1(i, tempRootNum);
//subEntityLevel1s.add(subEntityLevel1);
SubEntityLevel1Added event = new SubEntityLevel1Added(subEvents);
when(event);
tempEvents.add(event);
}
AggregateRootModifiedEvent event = new AggregateRootModifiedEvent(tempRootNum);
when(event);
tempEvents.add(event);
return tempEvents;
}
void when(AggregateRootModifiedEvent event){
this.rootNum = event.rootNum;
}
void when(SubEntityLevel1Added event){
SubEntityLevel1 subEntityLevel1 = new SubEntityLevel1();
for(Object subEvent : event.events){
subEntityLevel1.when(subEvent); //list of SubEntityLevel2Added AND SubEntityLevel1Initialized
}
subEntityLevel1s.add(subEntityLevel1);
}
}
class SubEntityLevel1{
int id;
List<SubEntityLevel2> subEntityLevel2s = new ArrayList<>();
int sum = 0;
List<Object> modify1(int id, int rootNum){
//this.id = id;
//this.sum = rootNum;
int tempSum = rootNum;
List<Object> tempEvents = new ArrayList<>();
for(int i=0; i<id; i++){
if(subEntityLevel2s.stream().noneMatch(se2 -> "0".equals(se2.id))) {
SubEntityLevel2 subEntityLevel2 = new SubEntityLevel2();
SubEntityLevel2Initialized event = subEntityLevel2.initialize(i);
//subEntityLevel2s.add(subEntityLevel2);
SubEntityLevel2Added event2 = new SubEntityLevel2Added(event);
when(event2);
tempEvents.add(event2);
//sum++;
tempSum++;
}
}
SubEntityLevel1Initialized event3 = new SubEntityLevel1Initialized(id, tempSum);
when(event3);
tempEvents.add(event3);
return tempEvents;
}
void when(SubEntityLevel1Initialized event){
this.id = event.id;
this.sum = event.sum;
}
void when(SubEntityLevel2Added event){
SubEntityLevel2 subEntityLevel2 = new SubEntityLevel2();
subEntityLevel2.when(event.event);
subEntityLevel2s.add(subEntityLevel2);
}
}
class SubEntityLevel2{
String id;
SubEntityLevel2Initialized initialize(int x){
SubEntityLevel2Initialized event = new SubEntityLevel2Initialized(String.valueOf(x));
when(event);
return event;
}
void when(SubEntityLevel2Initialized event){
this.id = event.id;
}
}
//----- EVENTS
class AggregateRootModifiedEvent{
int rootNum;
public AggregateRootModifiedEvent(int rootNum) {
this.rootNum = rootNum;
}
}
class SubEntityLevel1Added{
List<Object> events;
public SubEntityLevel1Added(List<Object> events) {
this.events = events;
}
}
class SubEntityLevel1Initialized {
int id;
int sum;
public SubEntityLevel1Initialized(int id, int sum) {
this.id = id;
this.sum = sum;
}
}
class SubEntityLevel2Added{
SubEntityLevel2Initialized event;
public SubEntityLevel2Added(SubEntityLevel2Initialized event) {
this.event = event;
}
}
class SubEntityLevel2Initialized {
String id;
SubEntityLevel2Initialized(String id){
this.id = id;
}
}
응답 해 주셔서 감사합니다. 내 문제를 좀 더 현실적으로 반영 했으므로 업데이트 된 질문을 확인해주십시오. 나는 아마도이 CreatedEvent를 가져야한다는 것에 동의한다. (하지만 위에 언급 된 새로운 질문에서는 이후에 그것을 참조하는 방법을 모른다.) 또한, 첫 번째 코드 스 니펫에서 답한대로 - 결국 집계 루트는 처음 실행할 때 이벤트를 적용 할 필요가 없습니다. 다시 수화 할 때만 가능합니다. 이벤트 소싱과 관련하여 Meyer의 패턴에 대한 예가 있습니까? – bojanv55
그러나 일반적인 힌트로 살펴 보겠습니다. DDD에 관해 질문 할 때마다 실제 문제에 대해 가능한 한 조심해야합니다. 일반적으로 일반적인 제약 조건을 가진 도메인은 지능적으로 모델을 작성하는 것이 어렵습니다. – VoiceOfUnreason