책책책

[DDD START!] 애그리거트를 통한 복잡한 도메인 모델 간 관계 관리

Deveun 2021. 8. 20. 05:42

도메인 주도 설계를 공부하며 등장한 애그리거트라는 개념과 그 역할에 대해서 알아보자.

 

쇼핑몰을 구현한다고 예를 들어보면, 내부에는 무수히 복잡하고 많은 도메인 모델들이 엮여있다.

Order라는 클래스는 OrderLine, ShippingInfo, PaymentInfo, Orderer 클래스들을 참조하고 또 다시 각각의 클래스들은 Receiver, Member, Product, Category 등등.. 개별의 객체 수준에서 모델을 바라보면 서로 관계를 파악하기가 어렵다. 이렇게 복잡한 도메인 객체모델들을 이해하고 관리하기 쉽도록 관련된 도메인을 하나의 상위 수준으로 묶어서 나타낸 것이 애그리거트이다. 

 

하나의 애그리거트에 속한 객체들은 동일한 라이프사이클을 가지고, 유사성을 지닌다 (함께 생성되고 함께 변경됨). 또한, 객체의 영속성을 처리하는 repository는 애그리거트 단위로 존재한다.

 

 

애그리거트 루트

: 동일 애그리거트에 속한 객체들은 항상 모두 정상상태로 일관성을 유지해야한다. 이 때, 이러한 상태의 책임을 지는 주체가 애그리거트의 루트엔티티가 되며, 애그리거트 내 모든 객체는 루트앤티티에 직/간접적으로 속해있다.

 

o 애그리거트 루트가 아닌 다른 객체에서 직접 상태가 변경되면 안된다. 

- set 메서드는 private 접근 범위로  만든다.

- Value는 불변 타입으로 구현하고, 변경이 필요할 시에는 애그리거트 루트 메서드에서 새로운 Value 객체를 전달해야한다.

==> 논리적 데이터 일관성 유지

 

[예제]

public class Order {

    // 참조클래스 (Value)
    private ShippingInfo shippingInfo;

    public void changeShippingInfo(ShippingInfo newShippingInfo) {
        setShippingInfo(newShippingInfo);
    }

    // set 메소드는 private 접근 범위로 구현
    // --> 애그리거트 외부에서 함부로 내부 상태를 바꾸지 못하도록.
    // 밸류타입의 내부상태 변경은 애그리거트 루트를 통해서만 가능
    // 밸류객체가 불변으로, 새로운 밸류 객체로 할당하여 변경
    private void setShipipngInfo(ShippingInfo newShippingInfo) {
        this.shippingInfo = newShippingInfo;
    }
}

 

o 하나의 트랜잭션은 하나의 애그리거트만 수정한다.

- 하나의 애그리거트에서 다른 애그리거트의 상태를 변경하면 안된다.

- 여러 애그리거트를 하나의 트랜젝션에서 변경해야할 경우, 응용서비스에서 @Transactional을 이용하여 구현한다.

==> save메소드, findById 매소드

 

 

[참고서적] DDD START! 도메인 주도설계 구현과 핵심 개념 익히기, 최범균 저자