핵심 인사이트 (3줄 요약)
- 본질: 에그리게이트 루트 (Aggregate Root)는 DDD의 전술적 패턴으로, 관련 도메인 객체들의 클러스터(에그리게이트)를 대표하는 단일 진입점 엔티티이며, 에그리게이트 내부 일관성을 보장하고 외부로부터 내부 객체에 대한 직접 접근을 차단하는 '일관성 경계'를 형성한다.
- 가치: 에그리게이트 루트를 통해서만 에그리게이트 내 모든 변경이 이루어지므로, 단일 트랜잭션 내 데이터 일관성이 자동으로 보장되고 불변 조건(Invariant) 위반이 방지된다.
- 판단 포인트: 에그리게이트 경계는 트랜잭션 일관성 요구사항에 기반해야 하며, '무엇이 항상 함께 변경되어야 하는가?'를 기준으로 결정해야 한다.
Ⅰ. 개요 및 필요성
에그리게이트(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)'를 고려해야 한다. 에그리게이트가 너무 크면 동시 수정 시 충돌이 잦아 성능 저하가 발생한다.
| 비교 축 | A | B |
|---|---|---|
| 트랜잭션 범위 | 좁음 → 충돌 적음 | 넓음 → 충돌 많음 |
| 일관성 | 에그리게이트 간 최종 일관성 | 에그리게이트 내 즉시 일관성 |
| 확장성 | 높음 | 낮음 |
- 📢 섹션 요약 비유: 에그리게이트 크기를 결정할 때는 '이 비즈니스 규칙이 동시에 일관성이 보장되어야 하는가?'를 먼저 묻는다.
Ⅳ. 실무 적용 및 기술사 판단
에그리게이트 루트를 통한 일관성 경계 설계로 데이터 무결성이 보장되고 도메인 불변 조건이 항상 유지된다. 에그리게이트 간 독립성 덕분에 성능 최적화(캐싱, 샤딩)도 용이해진다.
판단 체크리스트
- 에그리게이트 루트가 외부 참조의 유일한 진입점인가?
- 에그리게이트 경계가 비즈니스 불변 조건(Invariant)을 기준으로 정의되어 있는가?
- 에그리게이트가 작게 유지되어 잠금 충돌이 최소화되어 있는가?
- 에그리게이트 간 통신이 도메인 이벤트를 통해 이루어지고 있는가?
- 단일 트랜잭션에서 하나의 에그리게이트만 변경하는 원칙을 지키고 있는가?
- 📢 섹션 요약 비유: 에그리게이트 루트는 팀장과 같아서, 팀원(내부 객체)의 모든 변경사항을 팀장이 알고 승인해야 팀 전체의 일관성이 유지된다.
Ⅴ. 기대효과 및 결론
에그리게이트 루트를 통한 일관성 경계 설계로 데이터 무결성이 보장되고 도메인 불변 조건이 항상 유지된다. Event Sourcing과 에그리게이트의 자연스러운 통합(에그리게이트 상태 = 이벤트 시퀀스), CQRS와 결합한 에그리게이트 쓰기 최적화가 미래 방향이다.
한계는 에그리게이트 경계 설정이 어렵고, 잘못된 경계는 트랜잭션 복잡성이나 성능 저하를 유발한다. 에그리게이트 간 최종 일관성(eventual consistency)을 받아들여야 하는 비즈니스 교육이 필요하다.
- 📢 섹션 요약 비유: 에그리게이트는 레스토랑에서 하나의 주문서(루트)가 모든 메뉴 항목(내부 객체)을 관리하는 것과 같다.
📌 관련 개념 맵
[DDD 전술적 설계] → [에그리게이트 루트] → [일관성 경계] → [도메인 이벤트] → [CQRS+Event Sourcing]
| 개념 | 연결 포인트 |
|---|---|
| 엔티티 (Entity) | 에그리게이트 내 고유 식별자를 가진 도메인 객체 |
| 값 객체 (Value Object) | 식별자 없이 속성만으로 정의되는 불변 객체 |
| 도메인 이벤트 | 에그리게이트 간 최종 일관성 달성 수단 |
| 리포지토리 (Repository) | 에그리게이트 루트 단위로 영속화하는 저장소 |
📈 관련 키워드 및 발전 흐름도
[객체지향 설계 한계] → [DDD 전술 패턴] → [에그리게이트·루트] → [Event Sourcing 통합] → [CQRS 쓰기 모델] → [AI 경계 추천]
👶 어린이를 위한 3줄 비유 설명
- 에그리게이트 루트는 팀장처럼 팀 내 모든 변경을 관리해요.
- 외부에서는 팀장을 통해서만 팀원에게 연락할 수 있어요.
- 이렇게 하면 팀 전체가 항상 같은 정보를 유지할 수 있어요!