DDD 설계 원칙
TL;DR
- DDD 설계 원칙의 핵심 개념과 용어를 한눈에 정리한다.
- DDD 설계 원칙이(가) 등장한 배경과 필요성을 요약한다.
- DDD 설계 원칙의 특징과 적용 포인트를 빠르게 확인한다.
1. 개념
DDD 설계 원칙은(는) 핵심 용어와 정의를 정리한 주제로, 개발/운영 맥락에서 무엇을 의미하는지 설명한다.
2. 배경
기존 방식의 한계나 현업의 요구사항을 해결하기 위해 이 개념이 등장했다는 흐름을 이해하는 데 목적이 있다.
3. 이유
도입 이유는 보통 유지보수성, 성능, 안정성, 보안, 협업 효율 같은 실무 문제를 해결하기 위함이다.
4. 특징
- 핵심 정의와 범위를 명확히 한다.
- 실무 적용 시 선택 기준과 비교 포인트를 제공한다.
- 예시 중심으로 빠른 이해를 돕는다.
5. 상세 내용
작성일: 2026-02-24 카테고리: Backend / Architecture / DDD 포함 내용: DDD, Domain-Driven Design, Bounded Context, Ubiquitous Language, Aggregate, Entity, Value Object, Domain Event, Repository, Domain Service, Factory, Context Map, Anti-Corruption Layer, Rich Domain Model
1. DDD란 무엇인가
┌─────────────────────────────────────────────────────────┐
│ DDD = Domain-Driven Design │
│ (도메인 주도 설계) │
│ │
│ 창시자: Eric Evans │
│ 2003년 "Blue Book" 출간 │
│ (Domain-Driven Design: Tackling Complexity │
│ in the Heart of Software) │
│ │
│ 핵심 주장: │
│ ┌───────────────────────────────────────────────────┐ │
│ │ 소프트웨어 복잡성은 기술이 아닌 │ │
│ │ 비즈니스 도메인에서 온다. │ │
│ │ → 도메인을 중심에 두고 설계해야 한다. │ │
│ └───────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
배경: 왜 DDD가 등장했는가
┌─────────────────────────────────────────────────────────┐
│ 2000년대 초 엔터프라이즈 시스템 │
│ │
│ 문제 1: 기술과 비즈니스의 괴리 │
│ ├── 기술적으로 완벽한 시스템 │
│ └── 그러나 실제 비즈니스를 제대로 반영하지 못함 │
│ │
│ 문제 2: 소통 단절 │
│ ├── 개발자: DB 테이블 중심으로 사고 │
│ ├── 비즈니스 전문가: 자신의 언어로 사고 │
│ └── 번역 과정에서 의미 소실 │
│ │
│ ┌───────────────────────────────────────────────────┐ │
│ │ 기획자: "주문을 취소해줘" │ │
│ │ 개발자: updateOrderStatus(orderId, 0) │ │
│ │ │ │
│ │ → 0이 취소인지, 삭제인지, 대기인지 누가 알아? │ │
│ └───────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
2. 전략적 설계 (Strategic Design)
2-1. Domain (도메인)
┌─────────────────────────────────────────────────────────┐
│ Domain = 소프트웨어가 해결하려는 │
│ 비즈니스 영역 │
│ │
│ 도메인 하위 구분: │
│ │
│ ┌───────────────────────────────────────────────────┐ │
│ │ Core Domain (핵심 도메인) │ │
│ │ ├── 회사의 핵심 경쟁력 │ │
│ │ ├── 예: 쿠팡 = 물류/배송 최적화 │ │
│ │ └── 최고 인력 투입, DDD 집중 적용 │ │
│ │ │ │
│ │ Supporting Subdomain (지원 서브도메인) │ │
│ │ ├── 필요하지만 핵심 경쟁력은 아님 │ │
│ │ └── 예: 고객지원, 정산 │ │
│ │ │ │
│ │ Generic Subdomain (범용 서브도메인) │ │
│ │ ├── 범용적 해결책 존재 │ │
│ │ └── 예: 결제, 이메일 → 외부 솔루션 활용 │ │
│ └───────────────────────────────────────────────────┘ │
│ │
│ 핵심 원칙: 모든 곳에 동일 노력 쏟지 말것 │
│ Core Domain에 최고 인력과 DDD 집중 │
│ │
└─────────────────────────────────────────────────────────┘
2-2. Ubiquitous Language (보편 언어)
┌─────────────────────────────────────────────────────────┐
│ Ubiquitous Language = 개발자와 비즈니스 전문가가 │
│ 함께 사용하는 통일된 언어 │
│ │
│ 배경: │
│ ├── 기획자: "주문 취소" │
│ ├── 개발자: updateStatus(0) │
│ └── → 소통 단절, 의미 소실 │
│ │
│ 실천 예시: │
│ ┌───────────────────────────────────────────────────┐ │
│ │ ❌ order.setStatus(0) │ │
│ │ ✅ order.cancel(reason) │ │
│ │ │ │
│ │ ❌ if (user.getPoint() >= item.getPrice()) │ │
│ │ ✅ if (customer.canAfford(product)) │ │
│ └───────────────────────────────────────────────────┘ │
│ │
│ 규칙: │
│ ├── 코드/문서/대화 모두 같은 용어 사용 │
│ ├── 용어집 공동 관리 │
│ └── 새 용어 발견 시 즉시 코드에 반영 │
│ │
└─────────────────────────────────────────────────────────┘
2-3. Bounded Context (경계 맥락)
┌─────────────────────────────────────────────────────────┐
│ Bounded Context = 하나의 모델과 언어가 일관되게 │
│ 적용되는 경계 │
│ │
│ "Account"라는 단어 하나의 문제: │
│ ├── 은행 도메인: 예금계좌 │
│ ├── 인증 도메인: 사용자계정 │
│ └── 회계 도메인: 계정과목 │
│ → 하나의 모델로 통일 불가 → 경계를 긋자 │
│ │
│ ┌───────────────────────────────────────────────────┐ │
│ │ Sales Context │ Shipping Context │ Billing Ctx │ │
│ │ ───────────── │ ──────────────── │ ──────────── │ │
│ │ Customer │ Customer │ Customer │ │
│ │ = 계약 주체 │ = 배송지 정보 │ = 결제 정보 │ │
│ └───────────────────────────────────────────────────┘ │
│ │
│ 같은 단어라도 Context마다 의미와 모델이 다름 │
│ Big Ball of Mud를 방지하는 핵심 설계 원칙 │
│ │
└─────────────────────────────────────────────────────────┘
2-4. Context Map (컨텍스트 맵)
┌─────────────────────────────────────────────────────────┐
│ Context Map = 여러 BC 간 관계를 시각화한 지도 │
│ │
│ 8가지 관계 패턴: │
│ │
│ ① Partnership │
│ 두 팀이 대등하게 협력, 함께 계획/조율 │
│ │
│ ② Customer-Supplier │
│ 상류(Upstream) 팀이 하류(Downstream)에 제공 │
│ │
│ ③ Conformist (순응자) │
│ 하류가 상류 모델을 그대로 따름 │
│ │
│ ④ Anti-Corruption Layer │
│ 변환 계층으로 외부 모델의 오염 방지 │
│ │
│ ⑤ Shared Kernel (공유 커널) │
│ 두 팀이 작은 공통 모델을 공유 │
│ │
│ ⑥ Open Host Service │
│ 잘 정의된 API/프로토콜로 서비스 노출 │
│ │
│ ⑦ Published Language │
│ JSON Schema, Protobuf 등 문서화된 교환 형식 │
│ │
│ ⑧ Separate Ways (별도의 길) │
│ 통합하지 않음 (통합 비용 > 이득인 경우) │
│ │
└─────────────────────────────────────────────────────────┘
2-5. Anti-Corruption Layer (부패 방지 계층)
┌─────────────────────────────────────────────────────────┐
│ ACL = 외부 모델이 내 도메인을 "오염"시키지 않게 │
│ 막는 변환 계층 │
│ │
│ 배경: 이런 상황에서 필요 │
│ ├── 레거시 시스템과 연동 │
│ ├── 서드파티 API 사용 │
│ └── 다른 팀의 Bounded Context와 연동 │
│ │
│ 외부 모델 직접 사용 시 문제: │
│ ├── 외부 변경 시 내 코드 전체 수정 │
│ └── 이상한 네이밍 침투 (예: CUST_NM_01) │
│ │
│ ACL 적용: │
│ ┌───────────────────────────────────────────────────┐ │
│ │ 외부 모델 │ │
│ │ { CUST_NM_01: "김", ORD_AMT: 50000 } │ │
│ │ │ │ │
│ │ ▼ [Anti-Corruption Layer] │ │
│ │ │ 번역/변환 담당 │ │
│ │ ▼ │ │
│ │ 내 도메인 모델 │ │
│ │ Customer { name: "김" }, Order { amount: 50000 } │ │
│ └───────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
3. 전술적 설계 (Tactical Design)
3-1. Entity (엔티티)
┌─────────────────────────────────────────────────────────┐
│ Entity = 고유한 식별자(ID)로 구분되는 객체 │
│ 속성이 바뀌어도 같은 것으로 인식 │
│ │
│ 비유: │
│ "이름과 주소가 바뀌어도 주민번호가 같으면 같은 사람" │
│ │
│ 특징: │
│ ├── 고유 식별자(ID) 보유 │
│ ├── 속성 변경 가능 (mutable) │
│ ├── 동등성: ID가 같으면 같다 │
│ └── 라이프사이클 존재 (생성 → 수정 → 삭제) │
│ │
│ 예시: │
│ ├── Order (주문번호 = ID) │
│ ├── User (사용자ID = ID) │
│ └── Product (상품코드 = ID) │
│ │
└─────────────────────────────────────────────────────────┘
3-2. Value Object (값 객체)
┌─────────────────────────────────────────────────────────┐
│ Value Object = 식별자 없이 속성 값 자체로 의미를 갖는 │
│ 불변(Immutable) 객체 │
│ │
│ 배경: │
│ ├── "서울시 강남구"에 ID가 필요한가? → 아니오 │
│ └── "5000원"에 ID가 필요한가? → 아니오 │
│ 값이 같으면 같은 것 │
│ │
│ 특징: │
│ ├── 불변 (생성 후 변경 불가) │
│ ├── 변경 시 새 객체 생성 (교체) │
│ ├── 모든 속성이 같으면 같다 (동등성) │
│ └── 부수 효과 없음 │
│ │
│ ┌───────────────────────────────────────────────────┐ │
│ │ Money(5000, "KRW") == Money(5000, "KRW") → true │ │
│ │ Address("서울", "강남구") 수정 → 새 Address 생성 │ │
│ └───────────────────────────────────────────────────┘ │
│ │
│ 예시: │
│ ├── Money (금액 + 통화) │
│ ├── Address (주소 정보) │
│ └── Email, PhoneNumber, DateRange │
│ │
└─────────────────────────────────────────────────────────┘
3-3. Aggregate (집합체)
┌─────────────────────────────────────────────────────────┐
│ Aggregate = 하나의 단위로 다뤄야 하는 객체 묶음 │
│ 데이터 일관성의 경계 │
│ │
│ 배경: 왜 필요한가? │
│ ┌───────────────────────────────────────────────────┐ │
│ │ OrderItem의 price를 아무데서나 직접 수정하면? │ │
│ │ → Order.totalAmount와 불일치 발생! │ │
│ │ → 데이터 일관성 깨짐 │ │
│ └───────────────────────────────────────────────────┘ │
│ │
│ Aggregate 경계: │
│ ┌───────────────────────────────────────────────────┐ │
│ │ ┌─────────────────────────────────────────────┐ │ │
│ │ │ Aggregate │ │ │
│ │ │ ┌──────────────┐ │ │ │
│ │ │ │ Order (Root) │ ← 외부 접근 유일 창구 │ │ │
│ │ │ └──────────────┘ │ │ │
│ │ │ │ │ │ │
│ │ │ ┌────┴────────────┐ │ │ │
│ │ │ │ │ │ │ │
│ │ │ OrderItem ShippingAddress │ │ │
│ │ └─────────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────┘ │
│ │
│ 규칙: │
│ ├── 외부는 Root(Aggregate Root)만 접근 가능 │
│ ├── 하나의 트랜잭션 = 하나의 Aggregate │
│ └── Aggregate 간 참조는 ID로만 │
│ │
└─────────────────────────────────────────────────────────┘
3-4. Aggregate Root (집합체 루트)
┌─────────────────────────────────────────────────────────┐
│ Aggregate Root = Aggregate의 대표 Entity │
│ 외부와의 유일한 소통 창구 │
│ │
│ ✅ 올바른 접근: │
│ ├── order.addItem(product, quantity) │
│ ├── order.removeItem(itemId) │
│ └── order.cancel(reason) │
│ │
│ ❌ 잘못된 접근 (직접 접근 금지): │
│ ├── orderItem.delete() │
│ └── shippingAddress.change(newAddress) │
│ │
│ Repository도 Root 단위: │
│ ├── ✅ OrderRepository │
│ └── ❌ OrderItemRepository │
│ │
│ 이유: Root가 내부 일관성 보장 책임을 가짐 │
│ │
└─────────────────────────────────────────────────────────┘
3-5. Domain Event (도메인 이벤트)
┌─────────────────────────────────────────────────────────┐
│ Domain Event = 도메인에서 발생한 중요한 사건을 │
│ 객체로 표현한 것 │
│ │
│ 배경: 주문 완료 시 후속 처리 문제 │
│ ┌───────────────────────────────────────────────────┐ │
│ │ ❌ 강한 결합 방식: │ │
│ │ orderService.complete() { │ │
│ │ order.complete() │ │
│ │ inventoryService.decrease(order) // 재고 차감 │ │
│ │ notificationService.send(order) // 알림 발송 │ │
│ │ pointService.accumulate(order) // 포인트 │ │
│ │ } │ │
│ │ → OrderService가 모든 서비스에 의존 │ │
│ └───────────────────────────────────────────────────┘ │
│ │
│ ┌───────────────────────────────────────────────────┐ │
│ │ ✅ Domain Event 방식: │ │
│ │ order.complete() │ │
│ │ → registerEvent(OrderCompleted) │ │
│ │ │ │
│ │ InventoryListener → 재고 차감 │ │
│ │ NotificationListener → 알림 발송 │ │
│ │ PointListener → 포인트 적립 │ │
│ └───────────────────────────────────────────────────┘ │
│ │
│ 장점: │
│ ├── Order는 후속 처리를 몰라도 됨 │
│ ├── 새 처리 추가 = 새 리스너만 추가 │
│ └── Aggregate 간 느슨한 결합 │
│ │
└─────────────────────────────────────────────────────────┘
3-6. Repository (리포지토리)
┌─────────────────────────────────────────────────────────┐
│ Repository = Aggregate의 저장/조회를 추상화한 │
│ 인터페이스 │
│ │
│ 핵심 개념: │
│ "마치 메모리의 컬렉션에서 객체를 꺼내고 │
│ 넣는 것처럼 사용" │
│ │
│ 계층 구조: │
│ ┌───────────────────────────────────────────────────┐ │
│ │ Domain Layer │ │
│ │ interface OrderRepository { │ │
│ │ fun findById(id: OrderId): Order? │ │
│ │ fun save(order: Order) │ │
│ │ fun findByCustomerId(customerId: Id): List │ │
│ │ } │ │
│ │ │ (구현) │ │
│ │ Infrastructure Layer │ │
│ │ class JpaOrderRepository : OrderRepository { │ │
│ │ // JPA, MyBatis 등으로 실제 구현 │ │
│ │ } │ │
│ └───────────────────────────────────────────────────┘ │
│ │
│ 원칙: Aggregate Root 당 하나의 Repository │
│ │
└─────────────────────────────────────────────────────────┘
3-7. Domain Service (도메인 서비스)
┌─────────────────────────────────────────────────────────┐
│ Domain Service = 특정 Entity나 Value Object에 │
│ 속하지 않는 도메인 로직 │
│ │
│ 필요한 경우: │
│ ┌───────────────────────────────────────────────────┐ │
│ │ 계좌 A → 계좌 B 송금 │ │
│ │ │ │
│ │ accountA.transfer(accountB, amount) ? │ │
│ │ → A의 책임인가? │ │
│ │ │ │
│ │ accountB.receiveFrom(accountA, amount) ? │ │
│ │ → B의 책임인가? │ │
│ │ │ │
│ │ → 둘 다 어색! → TransferService가 담당 │ │
│ └───────────────────────────────────────────────────┘ │
│ │
│ 주의: │
│ 모든 로직을 Service에 넣으면 │
│ → Anemic Domain Model (안티패턴) │
│ │
│ Domain Service는 정말 어디에도 속하지 않을 때만 사용 │
│ │
└─────────────────────────────────────────────────────────┘
3-8. Factory (팩토리)
┌─────────────────────────────────────────────────────────┐
│ Factory = 복잡한 Aggregate/Entity 생성 로직을 │
│ 캡슐화하는 객체 │
│ │
│ 필요한 경우: │
│ ┌───────────────────────────────────────────────────┐ │
│ │ Order 생성 시 처리할 것들: │ │
│ │ ├── 주문 ID 생성 │ │
│ │ ├── 초기 상태 설정 │ │
│ │ ├── 유효성 검증 │ │
│ │ ├── 회원 등급별 할인 적용 │ │
│ │ └── 배송비 계산 │ │
│ │ │ │
│ │ → 생성자에 다 넣으면 너무 복잡 │ │
│ │ → OrderFactory.create(customer, items) 로 분리 │ │
│ └───────────────────────────────────────────────────┘ │
│ │
│ 적용 기준: │
│ ├── 단순 생성 → 생성자/정적 팩토리 메서드로 충분 │
│ └── 생성 자체가 복잡할 때만 Factory 도입 │
│ │
└─────────────────────────────────────────────────────────┘
4. 아키텍처 패턴
4-1. Layered Architecture (계층형 아키텍처)
┌─────────────────────────────────────────────────────────┐
│ Layered Architecture │
│ │
│ ┌───────────────────────────────────────────────────┐ │
│ │ Presentation Layer │ │
│ │ (Controller, API, UI) │ │
│ └───────────────────────────┬───────────────────────┘ │
│ │ 의존 │
│ ┌───────────────────────────▼───────────────────────┐ │
│ │ Application Layer │ │
│ │ (Use Case 조율, 트랜잭션 관리) │ │
│ └───────────────────────────┬───────────────────────┘ │
│ │ 의존 │
│ ┌───────────────────────────▼───────────────────────┐ │
│ │ Domain Layer ★ (핵심) │ │
│ │ (Entity, VO, Aggregate, Domain Service) │ │
│ │ 비즈니스 규칙 집중 │ │
│ └───────────────────────────┬───────────────────────┘ │
│ │ 의존 │
│ ┌───────────────────────────▼───────────────────────┐ │
│ │ Infrastructure Layer │ │
│ │ (DB, 외부 API, Repository 구현체) │ │
│ └───────────────────────────────────────────────────┘ │
│ │
│ 핵심 규칙: │
│ ├── 의존성은 위→아래 방향만 허용 │
│ └── Domain Layer는 다른 계층에 의존하지 않음 │
│ │
└─────────────────────────────────────────────────────────┘
4-2. Application Service vs Domain Service
┌─────────────────────────────────────────────────────────┐
│ Application Service vs Domain Service │
│ │
│ Application Service │
│ ├── Use Case 조율 │
│ │ "A 가져와서 → B에게 시키고 → C 저장" │
│ ├── 트랜잭션 관리 │
│ ├── 보안/인증 처리 │
│ └── 도메인 로직 자체를 포함하지 않음 │
│ │
│ ┌───────────────────────────────────────────────────┐ │
│ │ fun placeOrder(command: PlaceOrderCommand) { │ │
│ │ val customer = customerRepo.findById(...) │ │
│ │ val order = orderFactory.create(customer, ...) │ │
│ │ orderRepo.save(order) // 저장은 App Service │ │
│ │ } │ │
│ └───────────────────────────────────────────────────┘ │
│ │
│ Domain Service │
│ ├── 순수 비즈니스 로직 │
│ ├── 여러 Aggregate에 걸친 규칙 │
│ └── 기술적 관심사 없음 (트랜잭션, DB 몰라야 함) │
│ │
└─────────────────────────────────────────────────────────┘
5. 핵심 원칙 정리
5-1. Rich Domain Model vs Anemic Domain Model
┌─────────────────────────────────────────────────────────┐
│ Rich Domain Model vs Anemic Domain Model │
│ │
│ ❌ Anemic Domain Model (안티패턴): │
│ ┌───────────────────────────────────────────────────┐ │
│ │ class Order { │ │
│ │ var status: Int = 0 // getter/setter만 존재 │ │
│ │ var totalAmount: Long = 0 │ │
│ │ } │ │
│ │ │ │
│ │ // 모든 로직이 Service에: │ │
│ │ order.status = 0 // 아무데서나 상태 변경 가능! │ │
│ │ if (order.status == 0) { ... } // 의미 불분명 │ │
│ └───────────────────────────────────────────────────┘ │
│ │
│ ✅ Rich Domain Model (DDD 추구): │
│ ┌───────────────────────────────────────────────────┐ │
│ │ class Order { │ │
│ │ fun cancel(reason: String) { │ │
│ │ check(status != CANCELLED) { "이미 취소됨" } │ │
│ │ this.status = CANCELLED │ │
│ │ registerEvent(OrderCancelled(this, reason)) │ │
│ │ } │ │
│ │ fun addItem(product: Product, qty: Int) { ... }│ │
│ │ } │ │
│ └───────────────────────────────────────────────────┘ │
│ │
│ 차이: │
│ ├── 비즈니스 규칙이 도메인 객체 안에 캡슐화 │
│ └── 잘못된 상태 전이 차단 (불변식 보호) │
│ │
└─────────────────────────────────────────────────────────┘
5-2. Aggregate 설계 원칙
┌─────────────────────────────────────────────────────────┐
│ Vaughn Vernon (2013, "Implementing DDD" - Red Book) │
│ Aggregate 설계 4가지 규칙 │
│ │
│ 규칙 1: 작게 설계 │
│ ├── 큰 Aggregate = 동시성 충돌 증가 │
│ └── 큰 Aggregate = 성능 저하 │
│ │
│ 규칙 2: Aggregate 간 참조는 ID로만 │
│ ├── ❌ order.customer (Customer 객체 직접 참조) │
│ ├── ✅ order.customerId (ID만 참조) │
│ └── 직접 참조 → 거대 Aggregate로 진화 │
│ │
│ 규칙 3: 하나의 트랜잭션에서 하나의 Aggregate만 수정 │
│ └── 여러 Aggregate 수정 필요 → Domain Event 사용 │
│ │
│ 규칙 4: 결과적 일관성(Eventual Consistency) 허용 │
│ ├── Aggregate 내부: Strong Consistency │
│ └── Aggregate 간: Eventual Consistency 허용 │
│ │
└─────────────────────────────────────────────────────────┘
6. DDD를 적용해야 할 때 / 하지 말아야 할 때
┌─────────────────────────────────────────────────────────┐
│ DDD 적용 판단 기준 │
│ │
│ ✅ DDD 적용 권장: │
│ ├── 비즈니스 규칙이 복잡한 경우 │
│ │ (금융, 물류, 의료, 보험 등) │
│ ├── 도메인 전문가와 협업 가능한 경우 │
│ ├── 장기 유지보수가 필요한 시스템 │
│ └── 여러 팀이 협업하는 대규모 개발 │
│ │
│ ❌ DDD 비권장: │
│ ├── 단순 CRUD 시스템 (게시판, 설정 관리) │
│ ├── 프로토타입 / MVP (빠른 검증이 목적) │
│ ├── 도메인 전문가 접근이 불가능한 경우 │
│ └── 기술 중심 시스템 (ETL, 배치 처리) │
│ │
│ ┌───────────────────────────────────────────────────┐ │
│ │ Eric Evans의 조언: │ │
│ │ "비즈니스 복잡성이 진짜 문제인 곳에만 쓰세요. │ │
│ │ DDD는 도구이지, 종교가 아닙니다." │ │
│ └───────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
7. 용어 관계도
┌─────────────────────────────────────────────────────────┐
│ DDD 전체 구조 │
│ │
│ 전략적 설계 (Strategic Design) │
│ ├── Domain │
│ │ ├── Core Domain (핵심 경쟁력) │
│ │ ├── Supporting Subdomain │
│ │ └── Generic Subdomain │
│ │ │
│ ├── Bounded Context │
│ │ └── Ubiquitous Language (경계 안 통일 언어) │
│ │ │
│ └── Context Map (BC 간 관계 지도) │
│ ├── Anti-Corruption Layer │
│ ├── Shared Kernel │
│ ├── Customer-Supplier │
│ └── (그 외 5가지 패턴) │
│ │
│ 전술적 설계 (Tactical Design) │
│ ├── Aggregate │
│ │ ├── Aggregate Root (Entity) │
│ │ ├── Entity │
│ │ └── Value Object │
│ │ │
│ ├── Domain Event │
│ ├── Repository (저장 추상화) │
│ ├── Domain Service (도메인 로직) │
│ └── Factory (복잡한 생성 캡슐화) │
│ │
│ 아키텍처 │
│ ├── Layered Architecture │
│ │ ├── Presentation │
│ │ ├── Application │
│ │ ├── Domain ★ │
│ │ └── Infrastructure │
│ └── Hexagonal / Clean Architecture (변형) │
│ │
└─────────────────────────────────────────────────────────┘
관련 키워드
DDD, Domain-Driven Design, Bounded Context, Ubiquitous Language, Aggregate, Aggregate Root, Entity, Value Object, Domain Event, Repository, Domain Service, Factory, Context Map, Anti-Corruption Layer, Rich Domain Model, Anemic Domain Model, Core Domain, Strategic Design, Tactical Design, Layered Architecture, Eventual Consistency, 도메인 주도 설계, 보편 언어, 경계 맥락, 집합체, 값 객체, 도메인 이벤트