1) 애그리거트 루트란?
- 주문 애그리거트는 다음을 포함한다.
(1) 총 금액인 totalAmounts를 갖고 있는 Order 엔티티
(2) 개별 구매 상품의 개수인 quantity와 금액인 price를 갖고 있는 OrderLine 밸류
- 구매할 상품의 개수를 변경하면 한 OrderLine의 quantity를 변경하고
더불 Order의 totalAmounts도 변경해야 한다.
그렇지 않으면 다음 도메인의 규칙을 어기고 데이터 일관성이 깨진다
주문 총 금액은 개별 상품의 주문 개수 x 가격의 합이다.
- 애그리거트는 여러 객체로 구성되기 때문에 한 객체만 상태가 정상이면 안된다.
도메인 규칙을 지키려면 애그리거트에 속한 모든 객체가 정상 상태를 가져야 한다.
주문 애그리거트에서는 OrderLine을 변경하면 Order의 totalAmounts도 다시 계산해서 총 금액이 맞아야 한다.
- 애그리거트에 속한 모든 객체가 일관된 상태를 유지하려면 애그리거트 전체를 관리할 주체가 필요한데,
이 책임을 지는 것이 바로 애그리거트의 루트 엔티티이다.
애그리거트의 루트 엔티티는 애그리거트의 대표 엔티티다.
애그리거트에 속한 객체는 애그리거트 루트 엔티티에 직접 또는 간접적으로 속하게 된다.
- 주문 애그리거트에서 루트 역할을 하는 엔티티는 Order이다.
OrderLine, ShippingInfo, Orderer 등 주문 애그리거트에 속한 모델은 Order에 직접 또는 간접적으로 속한다.
2) 도메인 규칙과 일관성
- 애그리거트 루트가 단순히 애그리거트에 속한 객체를 포함하는 것으로 끝나는 것은 아니다.
애그리거트 루트의 핵심 역할은 애그리거트의 일관성이 깨지지 않도록 하는 것이다.
이를 위해 애그리거트 루트는 애그리거트가 제공해야 할 도메인 기능을 구현한다.
- 예를 들면, 주문 애그리거트는 배송지 변경, 상품 변경과 같은 기능을 제공하고,
애그리거트 루트인 Order가 이 기능을 구현한 메서드를 제공한다.
- 애그리거트 루트가 제공하는 메서드는 도메인 규칙에 따라 애그리거트에 속한
객체의 일관성이 깨지지 않도록 구현해야 한다.
- 배송이 시작되기 전까지만 배송지 정보를 변경할 수 있다는 규칙이 있다면,
애그리거트 루트인 Order의 changeShippingInfo() 메서드는 이 규칙에 따라
배송 시작 여부를 확인하고 규칙을 충족할 때만 배송지 정보를 변경해야 한다.
public class Order {
// 애그리거트 루트는 도메인 규칙을 구현한 기능을 제공한다.
public void changeShippingInfo(ShippingInfo newShippingInfo) {
verifyNotYetShipped();
setShippingInfo(newShippingInfo);
}
private void verifyNotYetShipped() {
if (state != OrderState.PAYMENT_WAITING && state != OrderState.PREPARING){
throw new IllegalStateException("already shipped");
}
}
...
}
- 애그리거트 외부에서 애그리거트에 속한 객체를 직접 변경하면 안된다.
이것은 애그리거트 루트가 강제하는 규칙을 적용할 수 없어 모델의 일관성을 깨는 원인이 된다.
'도메인 주도 개발 시작하기' 카테고리의 다른 글
[도메인 주도 개발 시작하기] 인프라스트럭쳐 개요 (0) | 2025.01.14 |
---|---|
[도메인 주도 개발 시작하기] 애그리거트의 영속성 전파 (0) | 2025.01.14 |
[도메인 주도 개발 시작하기] 애그리거트 로딩 전략 (0) | 2025.01.14 |
[도메인 주도 개발 시작하기] 바운디드 컨텍스트 (0) | 2025.01.14 |
[도메인 주도 개발 시작하기] 애그리거트 (0) | 2025.01.07 |