May 20, 2020
비즈니스 로직과 어댑터들로 구성
“메시지 채널”과 “이벤트”는 다른 건가에 대한 의문점
객체지향 설계 방식의 장점
각 클래스가 도메인 모델에서 수행하는 역할과 클래스의 특징을 정의.
애그리거트 : 한 단위로 취급 가능한 경계 내부의 도메인 객체들. 하나의 루트 엔터티와 하나 이상의 기타 엔터티 + 밸류 객체로 구성. 작업은 애그리거트 일부가 아니 전체 애그리거트에 적용하고, 보통 DB에서 통째로 가져오기 때문에 복잡한 지연 로딩 문제를 신경쓸 필요가 없다. 애그리거트를 삭제하면 해당 객체가 DB에서 모두 사라진다.
작으면 작을수록 좋다.
도메인 이벤트는 도메인 모델에서는 클래스 로 표현, 대부분 어떤 상태 변경을 나타냄.
과거 분사형 동사로 명명한 클래스. 이벤트에 의미를 부여하는 프로퍼티가 있는데, 프로퍼티는 원시 값(primitive value) 또는 밸류 객체(value object)이다. 이벤트ID, 타임스탬프 같은 메타데이터와 변경을 일으킨 사용자 신원정보도 존재 (감사-audit용도).
interface DomainEvent {} //자신을 구현한 클래스가 도메인 이벤트임을 알리는 마커 인터페이스!
interface OrderDomainEvent extends DomainEvent {} //Order 애그리거트가 발행한 OrderCreatedEvent의 마커 인터페이스
class OrderCreatedEvent implements OrderDomainEvent {}
interface DomainEventEnvelope<T extends DomainEvent> { //이벤트 객체 및 메타데이터를 조회하는 메서드가 존재. 이 인터페이스는 DomainEvent를 상속한 매개변수화 객체를 받는다.
String getAggregateId();
Message getMessage();
String getAggregateType();
String getEventId();
T getEvent();
}
이벤트 컨슈머가 이벤트를 받아 처리하려면 주문 내역이 필요함. 필요한 정보를 OrderService에서 가져와도 되지만, 이벤트 컨슈머가 서비스를 쿼리해서 애그리거트를 조회하는 것은 오버헤드를 유발. 그래서 컨슈머에 필요한 정보를 이벤트가 갖고 다니는 이벤트 강화(event enrichment) 기법을 적용한다.
강화된 OrderCreatedEvent
class OrderCreatedEvent implements OrderDomainEvent {
private List<OrderLineItem> lineItems;
private DeliveryInformation deliveryInformation; // 컨슈머가 필요로 하는 데이터
private PaymentInformation paymentInformation;
private long restaurantId;
private String restaurantName;
...
}
단점 : 컨슈머를 단순화하는 이점이 있지만, 컨슈머 요건이 바뀌면 이벤트 클래스도 함께 바꾸어야 하는 단점이 존재. => 이벤트 클래스의 안정성은 떨어진다.
이벤트 스토밍의 단계
아래 나머지 챕터에 대하여, 책의 샘플코드를 참고하는게 낫다.