핵심 인사이트 (3줄 요약)

  1. 본질: 에그리게이트 루트 (Aggregate Root)는 DDD의 전술적 패턴으로, 관련 도메인 객체들의 클러스터(에그리게이트)를 대표하는 단일 진입점 엔티티이며, 에그리게이트 내부 일관성을 보장하고 외부로부터 내부 객체에 대한 직접 접근을 차단하는 '일관성 경계'를 형성한다.
  2. 가치: 에그리게이트 루트를 통해서만 에그리게이트 내 모든 변경이 이루어지므로, 단일 트랜잭션 내 데이터 일관성이 자동으로 보장되고 불변 조건(Invariant) 위반이 방지된다.
  3. 판단 포인트: 에그리게이트 경계는 트랜잭션 일관성 요구사항에 기반해야 하며, '무엇이 항상 함께 변경되어야 하는가?'를 기준으로 결정해야 한다.

Ⅰ. 개요 및 필요성

에그리게이트(Aggregate)는 하나의 트랜잭션 내에서 함께 변경되어야 하는 관련 도메인 객체들의 묶음이다. 예를 들어 '주문(Order)'과 '주문 항목(OrderItem)'은 하나의 에그리게이트를 형성한다. 주문 항목은 주문 없이 존재할 수 없고, 주문 항목의 변경은 항상 주문 전체의 일관성(총액, 수량 합계)에 영향을 미치기 때문이다.

에그리게이트 루트는 이 에그리게이트의 진입점 역할을 하는 엔티티다. 외부에서는 에그리게이트 루트(Order)만 참조할 수 있고, 내부의 OrderItem에는 Order를 통해서만 접근한다.

┌─────────────────────────────────────────────────────────────┐
│            에그리게이트 구조 (Order 예시)                     │
├─────────────────────────────────────────────────────────────┤
│  외부 서비스 / 리포지토리                                    │
│       │                                                     │
│       ▼ (오직 루트만 참조 가능)                             │
│  ┌─────────────────────────────────────────────────────┐    │
│  │  Order (에그리게이트 루트)                            │    │
│  │  - orderId (식별자)                                  │    │
│  │  - status, totalAmount                              │    │
│  │  ├── OrderItem (내부 엔티티)                         │    │
│  │  │   - itemId, productId, quantity, price           │    │
│  │  └── ShippingAddress (값 객체)                       │    │
│  └─────────────────────────────────────────────────────┘    │
│  에그리게이트 경계: 단일 트랜잭션으로 일관성 보장            │
└─────────────────────────────────────────────────────────────┘
  • 📢 섹션 요약 비유: 에그리게이트는 회사 조직도처럼, 팀장(루트)을 통해서만 팀원(내부 객체)에게 업무 지시(변경)가 전달된다.

Ⅱ. 아키텍처 및 핵심 원리

에그리게이트 설계의 핵심 원칙: ① 에그리게이트 루트만 외부 참조 가능, ② 한 트랜잭션에서 하나의 에그리게이트만 변경, ③ 에그리게이트 간 이벤트로 최종 일관성 달성, ④ 에그리게이트는 작게 유지.

항목설명포인트
항상 함께 변경일관성 유지 위해 단일 트랜잭션 필요Order + OrderItem
비즈니스 불변 조건에그리게이트 내에서만 검증 가능한 규칙주문 총액 = 항목 합계
독립적 생존 불가부모 없이 존재 불가한 객체OrderItem은 Order 없이 불가
┌─────────────────────────────────────────────────────────────┐
│     에그리게이트 간 참조 패턴 (ID 참조 방식)                 │
├─────────────────────────────────────────────────────────────┤
│  [Order Aggregate]          [Product Aggregate]             │
│  Order { orderId, ... }     Product { productId, ... }      │
│  OrderItem { productId } ───ID만 참조──> (직접 참조 금지)   │
│                                                             │
│  에그리게이트 간 직접 참조 금지 → ID 참조 → 느슨한 결합     │
└─────────────────────────────────────────────────────────────┘
  • 📢 섹션 요약 비유: 에그리게이트는 성(城) 구조와 같다. 성문(루트)을 통해서만 성 안(에그리게이트)에 들어갈 수 있다.

Ⅲ. 비교 및 연결

에그리게이트 크기 결정은 '얼마나 자주 함께 잠기는가(lock contention)'를 고려해야 한다. 에그리게이트가 너무 크면 동시 수정 시 충돌이 잦아 성능 저하가 발생한다.

비교 축AB
트랜잭션 범위좁음 → 충돌 적음넓음 → 충돌 많음
일관성에그리게이트 간 최종 일관성에그리게이트 내 즉시 일관성
확장성높음낮음
  • 📢 섹션 요약 비유: 에그리게이트 크기를 결정할 때는 '이 비즈니스 규칙이 동시에 일관성이 보장되어야 하는가?'를 먼저 묻는다.

Ⅳ. 실무 적용 및 기술사 판단

에그리게이트 루트를 통한 일관성 경계 설계로 데이터 무결성이 보장되고 도메인 불변 조건이 항상 유지된다. 에그리게이트 간 독립성 덕분에 성능 최적화(캐싱, 샤딩)도 용이해진다.

판단 체크리스트

  1. 에그리게이트 루트가 외부 참조의 유일한 진입점인가?
  2. 에그리게이트 경계가 비즈니스 불변 조건(Invariant)을 기준으로 정의되어 있는가?
  3. 에그리게이트가 작게 유지되어 잠금 충돌이 최소화되어 있는가?
  4. 에그리게이트 간 통신이 도메인 이벤트를 통해 이루어지고 있는가?
  5. 단일 트랜잭션에서 하나의 에그리게이트만 변경하는 원칙을 지키고 있는가?
  • 📢 섹션 요약 비유: 에그리게이트 루트는 팀장과 같아서, 팀원(내부 객체)의 모든 변경사항을 팀장이 알고 승인해야 팀 전체의 일관성이 유지된다.

Ⅴ. 기대효과 및 결론

에그리게이트 루트를 통한 일관성 경계 설계로 데이터 무결성이 보장되고 도메인 불변 조건이 항상 유지된다. Event Sourcing과 에그리게이트의 자연스러운 통합(에그리게이트 상태 = 이벤트 시퀀스), CQRS와 결합한 에그리게이트 쓰기 최적화가 미래 방향이다.

한계는 에그리게이트 경계 설정이 어렵고, 잘못된 경계는 트랜잭션 복잡성이나 성능 저하를 유발한다. 에그리게이트 간 최종 일관성(eventual consistency)을 받아들여야 하는 비즈니스 교육이 필요하다.

  • 📢 섹션 요약 비유: 에그리게이트는 레스토랑에서 하나의 주문서(루트)가 모든 메뉴 항목(내부 객체)을 관리하는 것과 같다.

📌 관련 개념 맵

[DDD 전술적 설계] → [에그리게이트 루트] → [일관성 경계] → [도메인 이벤트] → [CQRS+Event Sourcing]

개념연결 포인트
엔티티 (Entity)에그리게이트 내 고유 식별자를 가진 도메인 객체
값 객체 (Value Object)식별자 없이 속성만으로 정의되는 불변 객체
도메인 이벤트에그리게이트 간 최종 일관성 달성 수단
리포지토리 (Repository)에그리게이트 루트 단위로 영속화하는 저장소

📈 관련 키워드 및 발전 흐름도

[객체지향 설계 한계] → [DDD 전술 패턴] → [에그리게이트·루트] → [Event Sourcing 통합] → [CQRS 쓰기 모델] → [AI 경계 추천]

👶 어린이를 위한 3줄 비유 설명

  1. 에그리게이트 루트는 팀장처럼 팀 내 모든 변경을 관리해요.
  2. 외부에서는 팀장을 통해서만 팀원에게 연락할 수 있어요.
  3. 이렇게 하면 팀 전체가 항상 같은 정보를 유지할 수 있어요!