ABOUT

성능과 운영 안정성을 함께 끌어올리는 개발자입니다.

92% Positional Error Reduction
79% p95 Latency Improvement
90%+ Long Tasks Reduction

2022.02 · 한국장학재단

우수 멘티

한국장학재단 사회 리더 대학생 멘토링 IT

2022.10 · 동작구청

우수 인재상

동작구청 우수 SW 인재

2025.05 · (주) 그랩

프로그래밍 우수상

(주) 그랩 우수 프로그램 개발

2025.05 · AWSKRUG

AWS한국사용자모임 발표

AI agent 스크립트 튜닝 관련 발표

ComputerScience

Development

Engineering

Trouble Shooting

GUESTBOOK

첫 마음부터
함께 나누는 온기

방명록 작성하러 가기

SUBSCRIBE

최신소식을
편하게 만나보세요.

Aggregate

도입

“객체 묶음”이 아니라, 일관성을 보장하는 트랜잭션 경계입니다.

DDD를 공부하다 보면 Entity, Value Object보다 Aggregate(애그리거트)에서 가장 많이 막힙니다.

이유는 개념 자체가 “클래스 구조”가 아니라 비즈니스 규칙 + 동시성 + 트랜잭션과 연결되기 때문입니다.

특히 실무에서는 “연관관계가 보이니까 다 묶자”라고 설계하면 금방 거대한 엔티티가 되고, 성능/락/변경 복잡도가 폭발합니다. 그래서 Aggregate는 객체 그래프의 크기가 아니라 일관성 경계(consistency boundary)로 이해하는 것이 핵심입니다.

핵심 메시지

“애그리거트는 함께 저장해야 하는 객체 묶음이 아니라,
한 번의 변경에서 반드시 지켜야 하는 규칙의 경계이다.”

- DDD 실무 설계 관점 -

 

정의

Aggregate는 연관된 객체(Entities / Value Objects)를 하나의 단위로 묶고, 그 내부의 규칙과 일관성을 보호하는 모델입니다.

애그리거트에는 항상 외부에서 접근하는 대표 객체가 존재하며, 이를 Aggregate Root(애그리거트 루트)라고 합니다. 외부는 루트를 통해서만 내부 상태를 변경해야 하고, 루트는 그 과정에서 도메인 규칙(불변조건)을 검사합니다.

💡 TIP / “관계가 있다” ≠ “같은 Aggregate”

Order와 Member, Product가 서로 연관되어 있어도 반드시 하나의 Aggregate일 필요는 없습니다. 한 트랜잭션 안에서 동시에 강한 일관성으로 묶어야 하는가?가 기준입니다.

 

구성 요소

Aggregate를 이해할 때는 루트, 내부 엔티티, 값 객체의 역할을 나눠서 보는 것이 좋습니다.
구성 요소 예시 설명
Aggregate Root Order 외부 접근의 유일한 진입점. 내부 상태 변경을 통제하고 규칙을 보장
Entity (내부) OrderLine 식별자를 가지는 내부 구성 요소. 루트의 통제 하에서만 변경
Value Object Money, Address 불변 값 중심 객체. 비교적 안전하게 조합/교체 가능
Repository OrderRepository Aggregate Root 기준으로 저장/조회. 내부 엔티티 단독 저장소를 두지 않음(일반적으로)

 

핵심 규칙

Aggregate 설계의 핵심은 “무엇을 묶을까?”보다 “어떤 규칙을 어디서 보장할까?”입니다.

1. 불변조건(Invariant)은 Aggregate 내부에서 지킨다

예를 들어 주문의 총액은 주문 항목 합계와 같아야 한다, 취소된 주문은 배송 시작 상태가 될 수 없다 같은 규칙은 컨트롤러나 UI가 아니라 Order Aggregate 내부 행동에서 보장해야 합니다.

2. 트랜잭션 경계는 Aggregate 단위로 잡는다

일반적으로 한 번의 명령(Command)에서 강한 일관성이 필요한 변경은 한 Aggregate 안에서 끝내는 것이 좋습니다. 여러 Aggregate를 한 트랜잭션에 강하게 묶기 시작하면 락 경쟁, 결합도 증가, 확장성 저하가 빠르게 나타납니다.

3. 외부 Aggregate는 객체 참조보다 ID 참조를 우선한다

Order가 Member, Product를 직접 객체로 들고 있으면 경계가 흐려지고 연쇄 로딩 문제가 생깁니다. 따라서 보통은 memberId, productId 같은 식별자만 보관하고, 필요한 정보는 애플리케이션 서비스나 조회 모델에서 조합합니다.

 

예시

주문(Order) Aggregate를 기준으로 보면 설계 원칙이 훨씬 선명해집니다.

Order Aggregate에 포함될 수 있는 것

  • Order (Root) : 주문 상태, 주문번호, 생성일시, 취소/확정 행위
  • OrderLine (Entity) : 상품별 수량/금액/할인 정보
  • Money / Address (VO) : 금액, 배송지

Order Aggregate에 보통 직접 포함하지 않는 것

  • Member Aggregate 전체 (memberId로 참조)
  • Product Aggregate 전체 (productId로 참조)
  • Inventory Aggregate 전체 (재고 차감은 별도 경계에서 처리, 필요 시 이벤트 활용)

주문 취소 규칙 예시

  • 배송 시작 전까지만 취소 가능
  • 이미 취소된 주문은 다시 취소할 수 없음
  • 취소 시 주문 상태 + 취소 시각 + 취소 사유가 함께 기록되어야 함

이런 규칙은 Order.cancel(...) 같은 루트 메서드에서 검사/변경해야 안전합니다.

 

설계 기준

좋은 Aggregate 설계는 작게 유지하면서도 규칙을 놓치지 않는 것에 가깝습니다.

1. 가능한 한 작게 유지하기

Aggregate가 커질수록 한 번의 변경에 읽고 잠그고 저장해야 하는 데이터가 늘어나 동시성 성능이 나빠집니다. “같이 조회된다”는 이유만으로 묶지 말고, 같이 변경되어야 하는가를 기준으로 판단합니다.

2. 조회 모델과 명령 모델 분리 고려하기

화면에 보여주기 위해 필요한 데이터 조합은 복잡할 수 있지만, 그것을 그대로 Aggregate에 넣을 필요는 없습니다. 명령(Command)에서는 규칙 중심 모델을 사용하고, 조회(Query)는 별도 DTO/읽기 모델로 최적화하면 설계가 훨씬 깔끔해집니다.

3. Aggregate 간 협력은 이벤트로 느슨하게 연결하기

주문 생성 후 재고 차감, 알림 발송, 포인트 적립 등은 다른 Aggregate/컨텍스트의 책임일 수 있습니다. 이때 한 트랜잭션에 모두 묶기보다 도메인 이벤트를 발행해 후속 처리를 분리하면 확장성과 변경 대응력이 좋아집니다.

 

JPA 실무 포인트

JPA를 쓴다고 해서 Aggregate 경계가 자동으로 만들어지지는 않습니다.
실수 개선 방향
연관관계 따라 무한 확장 객체 탐색 편의보다 경계/규칙/트랜잭션 기준으로 Aggregate를 자르기
Setter 남발 행위 메서드 중심으로 변경 (changeX, cancel, addLine 등)
루트 우회 수정 내부 엔티티를 외부에서 직접 조작하지 않도록 캡슐화
다중 Aggregate 강결합 트랜잭션 한 명령 = 한 Aggregate 원칙 우선, 후속 처리는 이벤트/비동기 고려

 

자주 하는 오해

Aggregate는 “도메인 객체를 많이 넣는 상자”가 아닙니다.

BAD

  • Order가 Member, Product, Inventory를 객체로 모두 소유
  • 내부 엔티티를 외부 서비스에서 직접 수정
  • 단순 조회 편의 때문에 경계를 확장
  • 트랜잭션 하나에 여러 Aggregate 변경을 습관적으로 묶음

GOOD

  • 루트를 통해서만 상태 변경
  • 불변조건을 루트/도메인 로직에서 보장
  • 다른 경계는 ID로 참조
  • 후속 처리는 이벤트로 분리해 느슨하게 연결

 

설계 체크리스트

Aggregate를 잡을 때 아래 질문으로 검증하면 실수가 줄어듭니다.

✅ 점검 질문

  • ✔️ 이 객체들은 한 번의 변경에서 함께 강한 일관성이 필요한가?
  • ✔️ 외부가 내부 엔티티를 직접 수정하지 못하게 루트가 통제하고 있는가?
  • ✔️ 조회 편의 때문에 Aggregate가 비정상적으로 커지지 않았는가?
  • ✔️ 다른 Aggregate와의 연관은 ID 참조로 충분하지 않은가?
  • ✔️ 동시성/락/성능 문제까지 고려했을 때 현재 경계가 현실적인가?

 

정리

Aggregate는 DDD의 핵심 단위이며, 도메인 규칙·트랜잭션·동시성 설계를 연결해주는 기준점입니다.

✅ 핵심 요약

  • ✔️ Aggregate는 단순 묶음이 아니라 일관성 경계입니다.
  • ✔️ 외부는 Aggregate Root를 통해서만 내부 상태를 변경해야 합니다.
  • ✔️ 다른 Aggregate는 객체 참조보다 ID 참조를 우선하는 것이 일반적입니다.
  • ✔️ Aggregate는 가능하면 작게 유지하고, 후속 처리는 이벤트로 분리하는 것이 좋습니다.
  • ✔️ 좋은 Aggregate 설계는 도메인 규칙뿐 아니라 성능/동시성/유지보수성까지 함께 개선합니다.
728x90