Strategic Design(전략적 설계)
Strategic Design (전략적 설계) 는 Eric Evans 가 제시한 Domain-Driven Design (도메인 주도 설계) 의 고수준 설계 접근법이다.
복잡한 비즈니스 도메인을 명확히 구분된 Bounded Context (경계 컨텍스트) 들로 분해하고, 각 컨텍스트 내에서 Ubiquitous Language (공통 언어) 를 구축하며, Context Map (컨텍스트 맵) 을 통해 컨텍스트 간 관계를 정의하여 대규모 소프트웨어 시스템의 복잡성을 체계적으로 관리한다.
이 그림 위에서 Tactical Design(전술 설계) 은 각 바운디드 콘텍스트 내에서 엔티티, VO, 어그리게이트, 리포지토리, 도메인 서비스, 도메인 이벤트 등의 빌딩 블록을 사용하여 도메인 로직을 구현하고 테스트, CI/CD 와 연계하여 구현 완성도를 높인다.
핵심 개념
Strategic Design은 복잡한 도메인을 분해하고, 하위 도메인 간의 관계를 명확하게 정의하여 **조직 구조, 소프트웨어 구조, 팀 협업 구조 간의 정렬 (alignment)**을 도출하는 고수준 설계 접근 방식이다.
주요 개념
Domain & Subdomain
항목 | 설명 |
---|---|
Domain | 소프트웨어가 해결하고자 하는 비즈니스 문제 영역 |
Subdomain | 도메인을 기능적으로 세분화한 논리적 단위 |
- 도메인을 이해하고 분해하는 것이 모든 설계의 출발점
- 도메인은 세 가지 유형으로 분류
Bounded Context (BC)
- 모델이 일관성을 가지는 명확한 경계 (Context) 를 의미
- BC 는 하나의 도메인 모델, 하나의 언어, 하나의 구현 책임 단위
- Microservice 의 자연스러운 단위
핵심 포인트:
- 동일한 단어도 서로 다른 BC 에서 다르게 해석될 수 있음
- 하나의 서브도메인에 여러 BC 가 존재할 수도 있음
Ubiquitous Language
- 도메인 전문가와 개발자 간 공통 언어
- 모델, 코드, 문서, 대화에 동일한 용어 사용
- 개념 간 불일치를 방지하고, 설계에 일관성 확보
Context Map
- 여러 Bounded Context 간의 관계를 시각화
- 통합 전략, 협력 방식, 의존성을 명시함
주요 Context Mapping Patterns
패턴 | 설명 |
---|---|
Shared Kernel | 일부 모델을 공유 (두 팀 간 강한 협력 요구) |
Customer/Supplier | 공급자 팀이 인터페이스를 제공하고, 고객 팀은 그에 의존 |
Conformist | 고객 팀이 공급자의 모델에 종속됨 |
Anticorruption Layer (ACL) | 외부 BC 로부터 내부 모델을 보호하는 번역 계층 |
Open Host Service | 공개 API 로 BC 간 통신 |
Published Language | 공통 언어와 형식을 정의하여 통합 |
실무 구현 요소
분석 및 설계 기법
기법 | 설명 |
---|---|
Event Storming | 도메인 이벤트 기반으로 도메인 흐름 시각화 |
Domain Storytelling | 도메인 전문가와 함께 스토리 기반 분석 |
Bounded Context Canvas | BC 설계를 위한 템플릿 기반 도구 |
조직적 대응
- 도메인별 팀 조직 (Team Topologies 와 결합 시 효과적)
- 각 Bounded Context 단위로 팀 분리 → Conway’s Law 대응
- 컨텍스트 간 API 또는 메시징 기반 통합 전략 적용
아키텍처 연계
- 각 BC 는 독립적인 배포/개발 단위 (→ Microservice Architecture 와 호환)
- ACL 적용으로 느슨한 결합 유지
- Context Map 은 기술적 아키텍처 구성의 기초 자료로 활용
정리
graph TD Domain[Domain] Domain --> Core[Core Domain] Domain --> Supporting[Supporting Domain] Domain --> Generic[Generic Domain] Core --> BC1[Bounded Context A] Supporting --> BC2[Bounded Context B] Generic --> BC3[Bounded Context C] BC1 --> UL1[Ubiquitous Language] BC2 --> UL2[Ubiquitous Language] BC3 --> UL3[Ubiquitous Language] BC1 --> CM[Context Map] BC2 --> CM BC3 --> CM CM --> SK[Shared Kernel] CM --> ACL[Anticorruption Layer] CM --> CS[Customer/Supplier] CM --> CON[Conformist]
목적 및 필요성
- 비즈니스 중심의 문제 영역 (Problem Space) 이해 및 핵심 도메인 식별.
- 도메인 전문가–개발자 간 이해 격차 해소 위해 공통 언어 (Ubiquitous Language) 구축.
- 컨텍스트 경계 설정으로 복잡도 분리, 팀 독립성·책임성 확보.
주요 기능 및 역할
도메인 분석 기능
- Problem Space 분석: 비즈니스 문제 영역을 체계적으로 분석
- Subdomain 식별: 도메인을 Core, Supporting, Generic 으로 분류
- 우선순위 결정: 비즈니스 가치에 따른 투자 우선순위 설정
모델 설계 기능
- Bounded Context 정의: 명확한 모델 경계 설정
- Ubiquitous Language 구축: 팀 전체가 공유하는 도메인 언어 개발
- Domain Model 설계: 각 컨텍스트별 최적화된 도메인 모델 구성
통합 관리 기능
- Context Mapping: 컨텍스트 간 관계와 통합 방식 정의
- Integration Pattern 선택: 상황에 적합한 통합 패턴 적용
- 의존성 관리: 컨텍스트 간 의존성을 명시적으로 관리
특징
고수준 접근법
- Big Picture 관점: 전체 시스템을 조감하는 거시적 시각
- 비즈니스 중심: 기술보다 비즈니스 가치를 우선시
- 전략적 사고: 장기적 관점에서의 시스템 설계
협업 중심
- 다학제적 접근: 도메인 전문가, 개발자, 아키텍트의 협업
- 지속적 학습: 도메인 지식의 지속적 발견과 정제
- 공통 언어: 모든 이해관계자가 공유하는 의사소통 도구
경계 중심 설계
- 명시적 경계: 모델의 적용 범위를 명확히 정의
- 컨텍스트 독립성: 각 컨텍스트의 자율성 보장
- 관계 명시: 컨텍스트 간 관계를 명시적으로 정의
핵심 원칙
모델 무결성 원칙
- 각 Bounded Context 내에서는 단일하고 일관된 모델 유지
- 모델의 개념적 무결성을 해치는 요소들 제거
경계 명시 원칙
- 모델이 적용되는 범위를 명확히 정의
- 경계를 넘나드는 개념들에 대한 명시적 변환 정의
공통 언어 원칙
- 팀 전체가 공유하는 Ubiquitous Language 구축
- 코드, 문서, 대화에서 일관된 언어 사용
비즈니스 가치 중심 원칙
- Core Domain 에 최대 투자 집중
- 비즈니스 우선순위에 따른 자원 배분
팀 자율성 원칙
- 각 팀이 자신의 컨텍스트 내에서 독립적으로 작업
- 팀 간 의존성 최소화
주요 원리
flowchart TD Problem-Space[문제 공간] --> Subdomain Subdomain --> BoundedContext BoundedContext --> UbiquitousLanguage BoundedContext --> ContextMap ContextMap --> IntegrationPatterns IntegrationPatterns --> Implementation
- Problem-Space: 도메인 분석
- Subdomain 식별: 핵심/지원/일반
- Context 설정: 모듈화
- 공통 언어 정의: 코드·사람 공유
- Context Map: 시스템 간 관계 자동화
- 통합 패턴: 경계 간 통신 전략
- 실행 연계: Tactical Design 과 구현 연동
분해 원리 (Decomposition Principle)
개념:
- 복잡한 도메인을 의미 있는 하위 도메인 (Subdomain) 으로 분해
- 각 Subdomain 을 Bounded Context 로 구체화하여 독립된 책임과 모델을 갖도록 설계
- 도메인 간 경계를 명확히 하여, 의미적 응집도 와 기술적 독립성 확보
실무 포인트:
- 하위 도메인마다 모델과 전략이 달라야 하며, 같은 아키텍처 스타일을 강제하지 않음
- 각 Subdomain 에 맞는 전략적 우선순위 (Core Domain 은 집중 투자)
graph TD A[Large Domain] --> B[Core Subdomain] A --> C[Supporting Subdomain] A --> D[Generic Subdomain] B --> E[Bounded Context 1] C --> F[Bounded Context 2] D --> G[Bounded Context 3]
통합 원리 (Integration Principle)
개념:
- 각각의 Bounded Context 는 고립되어 있지만, 전체 시스템에서 협력해야 함
- Context Mapping Patterns을 활용하여 경계 간 통합 방식을 정의
실무 포인트:
- 핵심 도메인 보호를 위해 ACL(Anti-Corruption Layer) 도입
- 하위 도메인의 중요도에 따라 종속성 방향, API 형태, 동기/비동기 방식 결정
주요 패턴:
패턴 | 설명 |
---|---|
Partnership | 상호 대등한 관계로 모델 공유와 협력 |
Customer-Supplier | 공급자 (Upstream) 는 독립적, 소비자 (Downstream) 는 종속적 |
Conformist | 소비자가 공급자의 모델을 강제로 따름 |
Open Host Service | 공식 API 를 통해 통합 |
Separate Ways | 통합하지 않고 완전히 분리 운영 |
graph LR A[Upstream Context] -->|Partnership| B[Downstream Context] C[Supplier Context] -->|Customer-Supplier| D[Consumer Context] E[Host Context] -->|Open Host Service| F[Client Context] G[Context A] -.->|Separate Ways| H[Context B]
언어 통일 원리 (Ubiquitous Language Principle)
개념:
- 도메인 전문가와 개발자가 동일한 언어로 소통
- 코드, 테스트, 문서, 회의에서 동일한 단어와 개념 사용
실무 포인트:
- 코드에 도메인 용어가 그대로 반영되어야 함
- 모델링 단계에서 나온 용어가 구현 코드까지 이어져야 함
전략적 정렬 원리 (Strategic Alignment Principle)
개념:
- 조직 구조, 도메인 구조, 시스템 구조를 정렬 (Alignment) 하여 일관성 있게 운영
- Conway’s Law 에 기반: 시스템 구조는 조직의 커뮤니케이션 구조를 반영하게 됨
실무 포인트:
- 도메인별 팀 구성 → 팀과 Bounded Context 1:1 매핑
- 전략적 중요도 (Core Domain) 높은 팀에 리소스 집중
예시 정렬 모델:
graph TD OrgA["Team A (Core Domain)"] --> BCA[Bounded Context A] OrgB["Team B (Supporting Domain)"] --> BCB[Bounded Context B] OrgC["Team C (Generic Domain)"] --> BCC[Bounded Context C]
경계 진화 원리 (Evolution of Boundaries Principle)
개념:
- 도메인 경계 (Bounded Context) 는 고정된 것이 아니며, 시간이 지남에 따라 비즈니스 변화나 인프라 요구에 따라 재조정될 수 있음
- 이를 통해 도메인 모델의 지속적 리팩토링 가능
실무 포인트:
- 도메인 리더와 협업하여 주기적 도메인 리디자인 워크숍 진행
- Context Map 을 지속적으로 업데이트
작동 원리
도메인 발견 과정
sequenceDiagram participant DE as Domain Expert participant A as Architect participant D as Developer DE->>A: 비즈니스 프로세스 설명 A->>D: 도메인 모델 초안 작성 D->>DE: 모델 검증 요청 DE->>A: 피드백 제공 A->>D: 모델 정제 Note over DE,D: 반복적 정제 과정
Bounded Context 식별 과정
- 언어 경계 식별: 용어의 의미가 변하는 지점 찾기
- 팀 경계 고려: 조직 구조와 의사소통 패턴 분석
- 기술 경계 평가: 기술적 제약사항과 요구사항 고려
- 비즈니스 기능 분석: 응집도가 높은 기능 그룹 식별
Context Mapping 과정
- 컨텍스트 식별: 모든 Bounded Context 나열
- 관계 분석: 컨텍스트 간 의존성과 상호작용 분석
- 패턴 선택: 각 관계에 적합한 통합 패턴 선택
- 맵 작성: 시각적 컨텍스트 맵 작성
구조 및 아키텍처
graph TB subgraph "Problem Space" PS[Problem Space] CD[Core Domain] SD[Supporting Domain] GD[Generic Domain] PS --> CD PS --> SD PS --> GD end subgraph "Solution Space" SS[Solution Space] BC1[Bounded Context 1] BC2[Bounded Context 2] BC3[Bounded Context 3] SS --> BC1 SS --> BC2 SS --> BC3 end subgraph "Language Layer" UL[Ubiquitous Language] UL --> BC1 UL --> BC2 UL --> BC3 end subgraph "Integration Layer" CM[Context Map] CM --> BC1 CM --> BC2 CM --> BC3 end
구분 | 구성요소 | 기능 | 역할 | 특징 |
---|---|---|---|---|
필수 | Problem Space (문제 공간) | 비즈니스 문제 영역 정의 | 해결해야 할 비즈니스 도메인 식별 | 현실 세계의 비즈니스 요구사항 반영 |
Solution Space (해결 공간) | 소프트웨어 구조 정의 | Bounded Context 집합 구성 | 기술 제약과 비즈니스 요구의 균형 | |
Bounded Context (경계 컨텍스트) | 도메인 모델 적용 경계 정의 | 모델 무결성 보장, 팀 자율성 제공 | 명시적 경계 내 일관된 모델 유지 | |
Ubiquitous Language (공통 언어) | 팀 전체 공유 도메인 언어 | 의사소통 효율, 모델 정확성 향상 | 코드와 회의에서 동일한 용어 사용 | |
선택 | Context Map (컨텍스트 맵) | 컨텍스트 간 관계 시각화 | 시스템 전체 구조 이해 및 통합 전략 설계 | 조직 구조와 기술 구조의 일치성 제공 |
Domain Events (도메인 이벤트) | 중요한 사건 모델링 | 컨텍스트 간 비동기 통신 구현 | 이벤트 기반 아키텍처 지원 | |
Anti-Corruption Layer (손상 방지 계층) | 외부 시스템으로부터 모델 보호 | 레거시 시스템과 안전한 통합 | 외부 변화로부터 내부 모델 분리 |
Problem Space (문제 공간)
정의:
- Problem Space는 소프트웨어가 해결하고자 하는 비즈니스 문제 도메인을 분석하고 정의하는 영역이다.
- " 무엇을 해결할 것인가?" 에 초점을 맞추며, 도메인의 구조와 서브도메인을 파악하는 것이 핵심이다.
주요 목적
- 비즈니스 목표, 정책, 흐름 등을 이해하고 구체화
- 도메인을 Core / Supporting / Generic 서브도메인으로 분류
- 도메인 전문가와의 협업을 통해 의미 있는 경계를 식별
핵심 질문:
- 어떤 도메인이 존재하는가?
- 어떤 도메인이 비즈니스에 가장 중요한가?
- 이 문제를 해결하려면 어떤 서브도메인이 필요한가?
실무 적용 포인트:
항목 | 내용 |
---|---|
도메인 분해 | 비즈니스 흐름 기반으로 서브도메인을 식별 |
우선순위 분석 | Core 도메인에 자원 집중, Generic 도메인은 외부 도입 고려 |
전략 정렬 | 비즈니스 전략과 소프트웨어 전략의 연계성 확보 |
추가 분석:
- 문제 공간은 비즈니스 전략과 정렬되는 방향으로 기능별 분할이 이루어져야 함.
- 문제 도메인의 이해 부족은 잘못된 컨텍스트 설계로 이어짐.
Subdomain
Subdomain 은 전체 도메인 안에서 특정한 목적이나 역할을 수행하는 하위 영역이며, 비즈니스 로직이 명확하게 구분될 수 있는 의미 단위의 경계이다.
필요성:
항목 | 설명 |
---|---|
복잡도 분리 | 하나의 도메인이 너무 커지면 이해, 관리, 구현이 어려움 → 하위 도메인으로 나눠서 책임 분리 |
설계 전략 구분 | 각 Subdomain 마다 기술/설계/아키텍처 접근 방식이 달라질 수 있음 |
팀 구조 연계 | 팀 간 경계, 업무 영역을 분리하여 병렬적 개발이 가능해짐 |
Bounded Context 연결 | Bounded Context 는 보통 하나의 Subdomain 을 구현하는 데 대응됨 |
Subdomain 분류
유형 | 설명 | 역할 | 실무 고려사항 | 특징 |
---|---|---|---|---|
Core Domain | 비즈니스 가치의 핵심 제공 영역 | 경쟁력 확보, 우선 순위 설계 대상 | 집중 투자, 고급 인력 배치 | 복잡성 높음, 커스터마이징 필요 |
Supporting Domain | Core Domain 을 보조하는 기능 | 비즈니스 흐름 지원 | 외주화 가능, 재사용률 높음 | 유사 사례 많음 |
Generic Domain | 범용 기능 제공 영역 | 시스템 전반에서 공통 활용 | 외부 솔루션 도입 가능 | 커스터마이징 필요 없음 |
graph TD A[비즈니스 도메인] --> B[하위 도메인 분리] B --> C1[핵심 하위 도메인] B --> C2[지원 하위 도메인] B --> C3[일반 하위 도메인] C1 --> D1[Bounded Context] C2 --> D2[Bounded Context] C3 --> D3[Bounded Context] D1 --> E[Context Map] D2 --> E D3 --> E
도메인 → 하위 도메인 → Bounded Context → Context Map 흐름
예시: 온라인 교육 플랫폼 (LMS)
Subdomain 유형 | Subdomain 예시 | 설명 |
---|---|---|
Core | 학습 콘텐츠 설계, 진도 추적, 시험 로직 | 학습자에게 가장 중요한 가치를 제공하는 핵심 영역 |
Supporting | 사용자 프로필 관리, 질문/답변 게시판 | 핵심은 아니지만 플랫폼 경험을 향상시키는 기능 |
Generic | 인증/인가, 로깅, 이메일 알림 | 모든 시스템에 공통 적용 가능, 비즈니스 독자성 없음 |
Subdomain vs. Bounded Context
항목 | Subdomain | Bounded Context |
---|---|---|
정의 | 비즈니스 로직 관점의 하위 도메인 | 설계 및 구현 관점에서 경계를 정의한 영역 |
관점 | 비즈니스 전략 중심 | 시스템 구현/모델링 중심 |
수 | 하나의 Subdomain 은 여러 개의 Bounded Context 가질 수 있음 | 하나의 Bounded Context 는 보통 하나의 Subdomain 과 연결 |
관계 | 전략적 설계의 단위 | 전술적 설계와 구현의 단위 |
Subdomain 은 " 무엇을 해야 하는지 " 를 설명하고, **Bounded Context 는 " 어떻게 구현할 것인지 " 를 결정하는 경계이다. **
Solution Space (해결 공간)
정의:
- Solution Space는 Problem Space 에서 정의된 문제를 해결하기 위한 소프트웨어 시스템 설계 공간이다.
- *" 어떻게 해결할 것인가?"* 를 다루며, Bounded Context 와 각 컨텍스트 간 관계 정의를 포함한다.
주요 목적:
- 경계를 명확히 설정하고, 기술적 책임 분리
- 각 문제 영역에 적합한 설계 패턴과 아키텍처 적용
- 팀 구성, 모듈화, 배포 전략과 연계
핵심 구성 요소:
- 여러 Bounded Context들의 집합
- 각 컨텍스트는 특정 Subdomain 에 매핑됨
- 통합 방식은 Context Map 으로 표현됨
실무 적용 포인트:
항목 | 내용 |
---|---|
아키텍처 적합성 | 도메인 특성에 따라 MSA, 모놀리식 등 설계 방식 결정 |
팀 구성 정렬 | 각 Bounded Context 를 독립된 팀이 담당 |
배포 전략 | BC 단위로 독립적 배포/운영 구조 확보 |
구성 요소:
세부 구성요소 | 설명 | 역할 | 실무 고려사항 | 특징 |
---|---|---|---|---|
Bounded Context 1~3 | 특정 도메인 모델의 적용 범위 | 기술 아키텍처, 팀 구조 정의 | 독립 배포 가능성, 경계 명확성 필수 | 소유된 모델과 언어 존재 |
Context Boundaries | 각 컨텍스트 간 명시적 경계 | 종속성, 통신 방식 정의 | API, 메시지 등 인터페이스 설계 필요 | 느슨한 결합 유지 |
Context Integration | 다수 컨텍스트 통합 메커니즘 | 전체 시스템 일관성 유지 | 이벤트, API, ACL 등 선택 | 조직 간 협업 요소 |
추가 분석:
- Solution Space 는 기술적 현실성과 조직 구조가 ** 정렬 (Alignment)** 되어야 효과적.
- " 도메인 중심 설계 vs 기술 중심 설계 " 충돌 방지를 위한 전략적 조율 필요.
Bounded Context
정의:
- Bounded Context는 특정 도메인 모델이 적용되는 명확한 논리적 경계를 의미한다.
- 같은 도메인이라도 다른 Bounded Context 에서 다른 의미로 사용될 수 있다.
주요 목적:
- 모델의 일관성과 무결성 유지
- 도메인 전문가와 개발자 간 소통 단위
- 코드, 모델, 언어, 테스트, 문서의 범위를 일치시킴
특징:
- 하나의 BC 는 하나의 Ubiquitous Language를 갖는다
- 팀 구조, 데이터베이스 스키마, 배포 단위로도 구분됨
구성 요소:
세부 구성요소 | 설명 | 역할 | 실무 고려사항 | 특징 |
---|---|---|---|---|
Domain Model | 해당 컨텍스트에서 사용하는 모델 | Ubiquitous Language 의 구현체 | 엔터티, VO, Aggregate 설계 필요 | 독립적 진화 가능 |
Team Ownership | 해당 컨텍스트를 책임지는 조직 | 책임 분리 및 팀 역량 집중 | 도메인과 조직 일치 필요 | Conway’s Law 기반 정렬 |
Autonomous Deployment | 자체 배포 단위로 설계 | DevOps 및 배포 독립성 확보 | CI/CD, 모듈 경계 최적화 | Microservice 적용 용이 |
Bounded Context 경계 식별 방법:
- 도메인 이벤트 중심 식별: Event Storming 등 워크숍을 통해 도메인 이벤트와 책임 주체를 시각화하여 자연스러운 경계 도출.
- Ubiquitous Language: 용어의 의미가 달라지는 지점을 경계로 삼아 BC 를 구분.
- 조직 구조 및 책임: 팀의 책임과 업무 흐름, Conway’s Law 에 따라 조직 구조와 BC 경계를 일치시키는 것이 효과적.
- 데이터 독립성: 데이터 모델이 독립적으로 진화할 수 있는 범위를 BC 로 설정.
경계 식별 기준:
기준 | 설명 |
---|---|
언어/의미 차이 | 같은 단어라도 의미가 다른 경우 (예: “Order” → 고객 주문 vs. 재고 발주) |
조직/책임 주체 차이 | 담당 조직 또는 팀이 다르면 BC 도 달라야 함 |
변화 속도/빈도 차이 | 자주 바뀌는 부분과 안정적인 부분은 분리 필요 |
독립 배포 여부 | 독립적으로 배포 가능한 단위는 별도 BC 로 취급 |
실무 적용 포인트:
항목 | 내용 |
---|---|
책임 분리 | BC 단위로 코드와 팀의 책임을 명확히 분리 |
독립 배포 | BC 를 독립적인 마이크로서비스로 구현 가능 |
내부 설계 | Tactical DDD (Entity, VO, Aggregate 등) 적용 |
실무 적용 확장:
적용 영역 | 세부 설명 |
---|---|
데이터베이스 | 각 Bounded Context 는 자신만의 DB 를 소유해야 함. DB 공유는 BC 의미 훼손 |
배포 | 독립적 CI/CD 파이프라인, 버전 관리 체계를 가져야 함 |
도메인 언어 관리 | 각 BC 별로 Ubiquitous Language 문서를 관리해야 하며, 타 BC 와의 상호작용 용어도 명시 |
테스트 | 컨텍스트 별로 계약 기반 테스트 (Contract Testing) 을 통해 통합 안정성 확보 필요 |
경계의 유연성 | 실제 운영 중에는 BC 경계를 주기적으로 재검토하고, 조직 변화나 도메인 진화에 따라 조정되어야 함 |
Bounded Context 와 Microservice 의 차이
- BC ≠ Microservice: BC 는 도메인 경계, Microservice 는 배포 단위로, 둘이 반드시 1:1 로 매핑되는 것은 아님.
- BC 내 다수의 Microservice: 하나의 BC 가 여러 Microservice 로 구현될 수 있으며, 반대로 여러 BC 가 하나의 서비스에 섞이면 도메인 혼란이 발생.
추가 분석:
- Bounded Context 는 하나의 도메인 서브시스템, 조직 단위, 배포 단위가 일치할수록 효과적.
- 내부 설계는 Tactical DDD 로 이어짐 (Entity, VO, Service, Repository 등).
Ubiquitous Language
정의:
- Ubiquitous Language란 도메인 전문가와 개발자가 공통적으로 사용하는 도메인 중심의 언어 체계
- 설계, 코드, 테스트, 문서, 대화 등 모든 곳에 일관되게 적용되는 모델링 언어.
- 도메인 지식이 정확하게 구현에 반영되도록 하는 소통 도구
- 해당 언어는 단순한 용어 수준이 아니라 도메인 개념, 규칙, 흐름을 포괄함
주요 목적:
목적 | 설명 |
---|---|
정확한 커뮤니케이션 | 개발자와 도메인 전문가 간의 의사소통 정확도 향상 |
도메인 지식 내재화 | 소프트웨어 내부에 비즈니스 규칙과 용어가 반영됨 |
모델 정합성 유지 | 코드, 테스트, 문서 전반에 걸쳐 일관된 도메인 모델을 사용 |
학습 곡선 감소 | 도메인 용어에 기반한 명확한 이해 공유로 온보딩 시간 단축 |
변화 대응성 향상 | 도메인의 변화가 모델과 언어에 반영되어 시스템 적응성 향상 |
핵심 질문:
- 도메인 전문가와 개발자가 사용하는 용어가 동일한가?
- 코드, 문서, 테스트, 대화에서 같은 개념이 일관된 의미로 표현되는가?
- 모델의 용어는 도메인을 진정으로 반영하고 있는가?
- 설계에서 발생하는 오해나 해석 오류가 언어 불일치에서 기인하지 않는가?
실무 적용 포인트:
항목 | 설명 |
---|---|
모델 기반 용어 정제 | 도메인 이벤트, 엔터티, 명세 등을 중심으로 명확한 개념 정의 |
코드에 언어 반영 | 메서드명, 클래스명, 패키지명 등에 도메인 용어 직접 사용 |
도메인 전문가 참여 유도 | 설계/모델링 시 비개발자의 언어가 존중되고 반영되어야 함 |
워크숍 도구 활용 | Event Storming, Domain Storytelling 등으로 언어 정렬 가능 |
용어 사전 작성 및 유지 | Bounded Context 단위로 관리되는 도메인 용어집 구축 필요 |
테스트에도 동일 언어 적용 | BDD(Behavior Driven Development) 에서 시나리오 기반 테스트 작성 (Given , When , Then ) |
구성 요소:
구성 요소 | 설명 |
---|---|
도메인 용어 집합 | 개념, 상태, 역할, 이벤트, 규칙 등 도메인에 특화된 언어 |
언어의 일관성 | 하나의 개념은 하나의 용어로만 표현되어야 함 |
경계 컨텍스트별 구분 | Ubiquitous Language 는 Bounded Context 에 종속됨 (즉, BC 마다 다를 수 있음) |
코드와 모델의 정합성 | 코드 구조와 도메인 모델 간의 이름과 구조가 일치 |
대화 기반 도출 | 언어는 도메인 전문가와 개발자 간의 지속적인 피드백을 통해 진화 |
Context Map (컨텍스트 맵)
정의:
- Context Map은 여러 Bounded Context 간의 관계와 통합 방식을 시각화한 설계 도구이다.
- 전략적 통합 패턴 (예: ACL, Shared Kernel 등) 을 기반으로 컨텍스트 간 상호작용을 정의한다.
주요 목적:
- 시스템 전체 구조 파악
- 컨텍스트 간 협력, 종속성, 커뮤니케이션 흐름 정의
- 조직 구조와 시스템 경계의 정렬
실무 적용 포인트:
항목 | 내용 |
---|---|
경계 명확화 | 각 팀과 시스템 사이의 경계 시각화 |
통합 전략 설계 | 이벤트 vs API 기반, 동기 vs 비동기 |
조직 연계 | 팀 간 계약 및 커뮤니케이션 프로토콜 정의 |
구성 요소:
세부 구성요소 | 설명 | 역할 | 실무 고려사항 | 특징 |
---|---|---|---|---|
Integration Pattern | 컨텍스트 간 통합 방식 정의 | 통신 및 의존성 패턴 설계 | 패턴: Shared Kernel, ACL 등 | 아키텍처 유연성 확보 |
Context Relationships | 컨텍스트 간 협력/의존 정의 | Upstream/Downstream 관계 명시 | 팀 간 커뮤니케이션 방식 영향 | 조직 구조 반영 |
Boundary Contracts | API 또는 이벤트 형식의 명세 | 명확한 경계 정의 | Interface 문서화, Test 필요 | 계약 기반 통신 구조 |
추가 분석:
- 컨텍스트 맵은 도식적 표현 (모델링) 뿐 아니라 운영 전략의 기술적 표현 역할도 수행.
- 팀 간 협업 프로세스, 제품 개발 흐름의 일관성을 높이는데 핵심적 기여.
Upstream, Downstream 그리고 Midway
Context Mapping에서 매우 중요한 개념으로, 두 컨텍스트 간 통신/통합 구조를 설계할 때 어떤 쪽이 주도권을 가지는지, 어떤 쪽이 종속되는지, 혹은 대등한 관계인지를 명확히 하기 위해 사용된다.
구분 | 정의 / 의미 | 주요 역할 | 관계 방향성 |
---|---|---|---|
Upstream | 다른 컨텍스트 (Downstream) 에서 사용하는 서비스, API, 이벤트를 제공하는 공급자 | 모델/인터페이스 설계 주도자 | → Downstream 에 영향 |
Downstream | Upstream 이 제공하는 기능 또는 데이터를 소비하는 주체 | 소비자, 통합자, 의존자 | ← Upstream 의 영향 받음 |
Midway | 두 컨텍스트가 대등한 협력 관계로 일부 기능/모델을 공동 관리하거나 상호 협의로 연동 | 공동 협업자, 협의 모델 관리자 | ↔ 상호 협력 및 동등 조율 |
- Upstream 은 계약 (API, 메시지, 스키마 등) 을 주도하고, Downstream 은 해당 계약을 기반으로 동작해야 한다.
- Upstream 의 변화는 Downstream 에 직접적 영향을 준다.
Upstream, Downstream 그리고 Midway 의 관계:
- Upstream: 표준 API 제공, 명세 주도, 변화 발생 시 영향 전파
- Downstream: Upstream 에 맞춰 적응, 변화를 수용
- Midway: 상호 협의로 모델/기능 설계, 동등한 책임과 권한
실무 적용 포인트:
- Upstream 은 서비스 제공자로서 책임 있는 인터페이스 관리와 버전 전략이 중요
- Downstream 은 소비자로서 변화에 유연하게 대응할 수 있는 구조 (예: ACL, Adapter) 가 필요
- Midway 는 협력 중심으로 커뮤니케이션 프로세스, 계약 문서화, 모델 공유 전략이 핵심
전략적 시사점:
- Upstream: 자율적 설계와 진화 가능하지만 Downstream 에 부담 전가 가능
- Downstream: 안정적인 API 기반 소비 가능하지만 Upstream 변화에 유연성 필요
- Midway: 협력이 필요한 경우 협의기구ㆍ공유 모델로 상호 조율 가능
주요 통합 패턴
구분 | 패턴 | 설명 | 관계 특성 | 장점 | 단점 | 실무 고려사항 |
---|---|---|---|---|---|---|
Upstream | Open Host Service (OHS) | API 또는 이벤트를 통해 외부에서 접근 가능한 서비스를 공식적으로 제공 | Upstream 이 명시적 인터페이스 제공 | 유연한 통합, 명확한 계약 | 보안, 버전 관리 필요 | 외부 컨텍스트와 표준화된 프로토콜 유지 필요 |
Published Language | 상호 간 통신을 위한 공통된 언어 또는 포맷 제공 | 계약 기반 메시지 교환 | 명확한 메시지 명세, 분산 시스템 적합 | 포맷 진화 어려움 | JSON, XML, Protobuf 등 표준 사용 권장 | |
Midway | Partnership | 두 컨텍스트가 동등한 협력자로 상호 의존 관계 형성 | 양방향 커뮤니케이션 | 긴밀한 협력 가능, 공유 목표 유지 | 동시 개발 부담, 커플링 증가 | 조직 간 책임 분배 및 의사소통 명확화 필요 |
Shared Kernel | 일부 모델이나 코드 (예: 공통 도메인 객체) 를 공유 | 부분적 모델 공유 | 코드 재사용, 중복 제거 | 변경 시 양쪽 모두 영향 | 공유 범위 최소화, 명확한 계약 필요 | |
Separate Ways | 각 컨텍스트가 독립적으로 운영되며 통합 없음 | 완전 분리 전략 | 빠른 진화, 독립성 극대화 | 중복 구현, 일관성 상실 위험 | 중복을 감수할 가치가 있는 도메인에 적합 | |
Downstream | Customer-Supplier | Downstream 이 Upstream 의 API 를 소비 | Upstream 중심 설계 | 빠른 통합, 계약 기반 통신 | 종속성 존재, 구조적 제약 | API 변경 시 영향 분석 필요 |
Conformist | Downstream 이 Upstream 의 모델과 언어를 그대로 수용 | 일방적 종속 관계 | 빠른 개발, 학습 비용 감소 | 유연성 없음, 변경 전파 영향 큼 | 비핵심 도메인에 적합, 장기적 유지보수 고려 | |
Anti-Corruption Layer (ACL) | 외부 시스템의 모델을 내부로 직접 들여오지 않고 번역 계층을 둠 | Upstream 격리 | 내부 모델 보호, 유연한 통합 | 복잡한 중간 계층 필요 | 통합 비용 증가 대비 보호 가치가 있는지 검토 |
Open Host Service (OHS)
활용 사례: 결제 시스템, 사용자 인증 서비스 등에서 공식 REST API, gRPC, GraphQL 등 표준 프로토콜로 외부에 서비스 제공.
사용 예시: 드론 배송 서비스에서 배송 (Shipping) 컨텍스트가 OpenAPI/Swagger 로 REST API 를 공개하여, 다른 컨텍스트 (예: 사용자 계정, 드론 관리) 가 표준화된 방식으로 접근.
코드 예시:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
# openapi.yaml 일부 예시 paths: /delivery: get: summary: "배송 목록 조회" responses: '200': description: "성공" content: application/json: schema: type: array items: $ref: '#/components/schemas/Delivery' components: schemas: Delivery: type: object properties: id: type: integer status: type: string
- 명세 기반 인터페이스: OHS 의 대표적인 문서화 방법
- Swagger UI 또는 Codegen 을 통해 클라이언트 자동 생성 가능
- API 안정성과 계약 유지에 기여
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
from fastapi import FastAPI, HTTPException, Depends from pydantic import BaseModel, Field from typing import List app = FastAPI(title="Shipping Service", version="1.0") class Delivery(BaseModel): id: int = Field(..., example=1) status: str = Field(..., example="in-transit") def get_current_user(): # 인증 로직 생략 (JWT 또는 OAuth2) return "external_service_consumer" @app.get("/v1/delivery", response_model=List[Delivery]) def get_deliveries(user=Depends(get_current_user)): try: return [ {"id": 1, "status": "delivered"}, {"id": 2, "status": "in-transit"} ] except Exception as e: raise HTTPException(status_code=500, detail=str(e))
Depends
→ 인증/인가 처리tags
→ Swagger 그룹화HTTPException
→ 명시적 에러 계약- FastAPI 는 자체적으로 OpenAPI 명세를
/docs
로 제공 → OHS 에 최적 - 표준 HTTP 방식 사용 + JSON 응답 → OHS 의 ’ 명시적 공개 API’ 와 일치
- 실무적으로도 많이 사용되는 구조
Published Language
활용 사례: 금융 (ISO 20022), 물류 (EDI), 플랫폼 간 통신에서 명시적 메시지 포맷 (Avro, Protobuf) 을 정의하여 상호 시스템 간의 데이터 교환에 활용.
사용 예시: 드론 배송 시스템이
delivery.proto
메시지 스키마를 Schema Registry 또는 공유 Git 저장소에 공개하고, 주문 시스템이 해당 메시지 형식을 기준으로 Kafka 이벤트를 발행하거나 gRPC 호출을 수행.코드 예시 (Protobuf 메시지 정의):
- 메시지 포맷을 명확히 정의하고, 버전 관리 체계화.
proto3
명세로 최신 protobuf 지원- 필드 번호 지정 → 향후 변경 대비 확장성 우수
- 메시지 구조 명확 → 여러 언어에서 동일 구조 생성 가능 (Java, Python, JS 등)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
# delivery_pb2.py 로 컴파일된 Protobuf 메시지 사용 from delivery_pb2 import DeliveryRequest, Address req = DeliveryRequest( userId="user-123", packageId="pkg-456", address=Address( street="123 Drone St", city="Seoul", zipCode="12345" ), version=1 ) # Serialize (Kafka 전송 or gRPC 호출에 활용) payload = req.SerializeToString()
Partnership
활용 사례: 대형 금융사와 핀테크 기업 간 협업에서, 공동으로 비즈니스 로직과 계약 명세 (API, 메시지 포맷 등) 를 설계하고, 양측이 동등한 책임을 지며 통신 및 개발을 수행하는 경우.
사용 예시: 두 개발 팀이 **공동의 API 명세 (OpenAPI)**와 **공통 메시지 스키마 (JSON Schema, Protobuf 등)**를 협의하고, 이를 버전 관리되는 명세 저장소에서 관리. 각 팀은 별도의 시스템을 운영하지만, 서로의 API 변화에 대한 영향을 고려하여 동시 릴리스 계획을 수립하고, 계약 기반 테스트 (Pact, Swagger Diff) 등을 함께 유지.
코드 예시:
- 양방향 API 통신
- 서로 다른 시스템이 서로에게 의존
- 데이터/도메인 설계는 분리, 하지만 공동 목표를 위해 지속적 협의
Shared Kernel
활용 사례: 고객 시스템과 결제 시스템이 공통된 인증 도메인 모델과 정책 유효성 검증 로직을 공유하며, 이 코드를 공동으로 관리하고 유지함.
사용 예시: 고객 관리 컨텍스트와 상품 추천 컨텍스트가 Customer 도메인 객체를 공동 정의하여 사용하고, 해당 모델 변경 시 공동 리뷰 및 버전 호환성 테스트를 거쳐 릴리즈를 조율함.
코드 예시:
- 비즈니스 규칙 포함: 단순 데이터 모델이 아닌 도메인 객체
- 검증 포함: 유효성 검사 로직 포함
- 함수적 행위 포함: 모델의 행위적 책임 부여
- → 이런 구조는 Shared Kernel 의 의미를 더 잘 드러냄
Separate Ways
활용 사례: 서로 다른 공급사의 ERP 및 CRM 시스템을 조직 내에서 독립적으로 운영. 고객 정보가 양 시스템에 중복 저장되지만, 각 시스템이 별도의 기능, 정책, 배포 주기를 가지므로 통합을 포기하고 각자 진화시킴.
사용 예시: 병원 시스템에서 예약은 프론트 데스크에서, 진료는 의료진이 사용하는 시스템에서 관리되며, 두 컨텍스트는 물리적/논리적으로 완전히 분리됨. 환자 정보는 각 시스템에서 개별 저장 및 운영되고, 데이터는 일치하지 않아도 무방한 구조로 설계됨.
코드 예시:
1 2 3 4 5 6 7 8 9 10 11
# 예약 시스템 - 예약 도메인 모델 (reservation_service/models.py) class Reservation: def __init__(self, patient_id, schedule_time): self.patient_id = patient_id self.schedule_time = schedule_time # 진료 시스템 - 진료 도메인 모델 (treatment_service/models.py) class Treatment: def __init__(self, patient_id, diagnosis): self.patient_id = patient_id self.diagnosis = diagnosis
- 두 시스템은 파일/모듈 구조 자체가 다르며 독립적 저장소, 배포, 개발팀에 의해 관리됨
- 참조나 연동 없이 자체 로직 기반 처리
- 데이터 중복 허용, 일관성 보장 안 해도 되는 구조
Customer-Supplier
활용 사례: 주문 서비스가 결제 API 를 호출하거나, 사용자 인증 서비스가 다른 마이크로서비스에 인증 기능을 제공하는 경우처럼, Downstream 이 Upstream 의 안정된 계약 (API 명세) 에 의존하는 구조. 변경이 발생하면 하위 호환성 유지가 중요하며, 계약 테스트 및 API 버전 관리가 핵심.
사용 예시: 주문 생성 시 결제 API 호출은 반드시 사전에 합의된 API 명세 (OpenAPI 등) 에 기반하여 개발되며, 명세 변경 시 하위 시스템에 영향이 없도록 Pact 등을 통해 계약 테스트가 수행된다.
코드 예시:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
import requests class PaymentServiceClient: BASE_URL = "https://payment-service/api/v1" def __init__(self, token: str): self.headers = {"Authorization": f"Bearer {token}"} def pay_order(self, order_id: str, amount: float) -> dict: try: response = requests.post( f"{self.BASE_URL}/pay", headers=self.headers, json={"order_id": order_id, "amount": amount}, timeout=5 ) response.raise_for_status() return response.json() except requests.RequestException as e: # 실패 시 로깅 및 fallback 처리 raise RuntimeError(f"결제 API 호출 실패: {e}")
- URI 버전 명시
- 인증 토큰 처리
- 예외 처리 및 안정성 확보
- 향후 API 스펙 변경에 대비 가능
Conformist
활용 사례: 외부 결제 게이트웨이 (PG 사) 또는 OAuth 인증 시스템 (Google, Kakao 등) 과의 연동에서, 소비자는 제공자의 API/데이터 구조를 그대로 수용한다. 이 경우, 공급자의 변경에 대해 협상 없이 그대로 따르게 되며, Downstream 은 Upstream 에 완전히 종속된다.
사용 예시: 외부 API 에서 응답받은
status
,transaction_id
구조를 별도의 변환 없이 서비스 로직과 UI 로직에 그대로 사용. API 명세가 바뀌면 Downstream 전체가 영향을 받음.코드 예시:
1 2 3 4 5 6 7 8 9 10 11 12
# 외부 결제 서비스 API 응답 (Upstream 모델 그대로 사용) class PaymentResponse: def __init__(self, status, transaction_id): self.status = status self.transaction_id = transaction_id # 내부 주문 도메인에서 직접 사용 (변환 계층 없이) def handle_payment_result(response: PaymentResponse): if response.status == "SUCCESS": print(f"거래 완료: {response.transaction_id}") else: print("결제 실패")
PaymentResponse
는 외부 API 명세 기반 모델handle_payment_result()
함수는 이를 도메인 내부에서 직접 사용- 변환 계층 (ACL, Adapter 등) 없이 그대로 사용하는 구조 → Conformist 패턴의 본질
Anti-Corruption Layer (ACL)
활용 사례: 레거시 시스템 또는 외부 API 의 도메인 모델이 내부 설계와 맞지 않거나, 통합 시 내부 도메인의 규칙을 침범할 우려가 있을 때, 중간 계층에서 Adapter 또는 Translator 를 통해 외부 모델을 내부 도메인 모델로 변환. 이를 통해 결합도를 낮추고 변경에 대한 격리를 확보함.
사용 예시: 외부 주문 시스템에서 수신된
LegacyOrder
를 내부Order
도메인 모델로 변환하는LegacyOrderAdapter
를 구현. 외부 시스템 변경 시에도 Adapter 만 수정하면 되고, 내부 도메인 로직은 영향을 받지 않음.**코드 예시 **:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
# 외부 시스템에서 받은 객체 (레거시 모델) class LegacyOrder: def __init__(self, order_id, customer_name, item_list): self.order_id = order_id self.customer_name = customer_name self.item_list = item_list # 문자열 목록 (ex: ["item1:2", "item2:1"]) # 내부 도메인 모델 class OrderItem: def __init__(self, name, quantity): self.name = name self.quantity = quantity class Order: def __init__(self, id, customer, items): self.id = id self.customer = customer self.items = items # List[OrderItem] # ACL - Adapter class LegacyOrderAdapter: @staticmethod def convert(legacy_order: LegacyOrder) -> Order: items = [] for item_str in legacy_order.item_list: name, qty = item_str.split(":") items.append(OrderItem(name=name.strip(), quantity=int(qty))) return Order( id=legacy_order.order_id, customer=legacy_order.customer_name, items=items )
- 외부의 레거시 모델
LegacyOrder
는 내부에서 직접 사용하지 않음 - 내부 도메인 모델
Order
,OrderItem
은 자체 규칙에 따라 정의됨 LegacyOrderAdapter
는 외부→내부 번역 계층이며, ACL 의 구현체
- 외부의 레거시 모델
요약
패턴 | 활용 사례 / 사용 예시 | 코드 / 구현 방식 요약 |
---|---|---|
Open Host Service (OHS) | - 결제, 배송, 인증 등 핵심 서비스 API 공개 - 이벤트 발행을 통한 외부 접근 제공 | - REST/gRPC/GraphQL API 제공 - OpenAPI/Swagger 문서화 - 인증/인가 적용, 버전 관리 |
Published Language | - Protobuf/Avro 기반 이벤트 메시지 통신 - 산업 표준 메시지 (EDI, ISO 20022 등) 연동 | - 스키마 파일로 메시지 정의 (.proto , .avsc )- 버전 관리, 타입 안정성 확보 - Schema Registry 활용 가능 |
Partnership | - 대형 금융사 ↔ 핀테크 협업 - 공동 개발 및 양방향 통신 - 정산 로직, 정책 공통 모듈 개발 협업 | - 공동 저장소에서 API/명세/계약 관리 - 정기적 협의, 커플링 있음 - Swagger, Pact 계약 테스트 병행 가능 |
Shared Kernel | - 인증 모듈, 도메인 유효성 검사, 예외 공통 처리 - 공통 도메인 모델 ( Customer , Product ) 공유 | - 공통 패키지/모듈 분리 - 도메인 모델 공유 및 영향도 분석 - 변경 시 공동 코드 리뷰 및 계약 관리 필수 |
Separate Ways | - ERP/CRM 시스템 분리 운영 - 병원 진료/예약 컨텍스트 분리 - 데이터/로직 중복 감수 | - 모델/시스템/DB 완전 분리 - 동기화 없음, 통합 없음 - 중복 구현 감수하며 각자 진화 |
Customer–Supplier | - 주문 시스템 → 결제 시스템 API 호출 - 사용자 서비스 → 인증 서비스 사용 - 계약 기반 통신 구조 | - REST API 기반 요청/응답 - 명세 기반 개발 (OpenAPI) - SLA 정의, 하위 호환성 유지 전략 필요 |
Conformist | - 외부 OAuth/SSO 연동 - PG 사 결제 응답 포맷 그대로 수용 - 클라이언트 SDK 그대로 사용 | - Upstream 모델 구조 그대로 사용 - DTO/Adapter 없이 직접 참조 - API 변경 시 즉시 영향 |
Anti-Corruption Layer | - 레거시 시스템 통합 - 3rd party 시스템 연동 - 의미 매핑 불일치 해결 | - Adapter / Translator / Facade 계층 구현 - 외부 모델 → 내부 도메인 변환 - 내부 도메인 보호, 격리 유지 |
OHS
,Published Language
는 Upstream 주도형 패턴Customer-Supplier
,Conformist
,ACL
은 Downstream 통합 전략Partnership
,Shared Kernel
은 Midway 협력 패턴Separate Ways
는 전략적 비통합을 의도한 극단적 분리 전략
구현 기법
구현 기법 | 정의 | 구성 요소 | 목적 | 실무 예시 |
---|---|---|---|---|
Event Storming | 도메인 이벤트 중심의 협업적 모델링 기법 | Domain Events, Commands, Aggregates, External Systems | 도메인 지식 발견, Bounded Context 식별 | 주문 처리 프로세스: 주문 생성됨 → 재고 확인됨 → 결제 처리됨 → 배송 시작됨 |
Domain Storytelling | 액터 중심의 스토리 기반 도메인 분석 기법 | Actors, Work Objects, Activities, Annotations | 비즈니스 프로세스 시각화 및 이해 | " 고객이 주문 생성 → 시스템이 재고 확인 " 흐름을 시각적으로 표현 |
Bounded Context Canvas | Bounded Context 를 정의하고 문서화하는 구조화 템플릿 | Name, Purpose, Business Model, Ubiquitous Language | 경계 컨텍스트의 책임, 인터페이스, 모델 정의 | " 주문 관리 " 컨텍스트의 모델, 언어, 책임 도출 및 정리 |
Context Mapping Workshop | 여러 Bounded Context 간 관계 정의 및 통합 전략 수립을 위한 워크숍 | Context 식별, 관계 설정, 통합 패턴 선택 | 시스템 전체 구조 정리 및 협력 방식 설정 | 전자상거래 전반의 BC 관계를 Customer-Supplier , ACL 등으로 연결 |
구현 기법 예시
드론 배송 시스템을 실제 사례로 활용한 DDD 구현 기법 예시
템플릿 유형 | 활용 시점 | 목적 |
---|---|---|
Event Storming | 초기 도메인 흐름 식별 시 | 이벤트 흐름 기반 컨텍스트 구조 도출 |
Domain Storytelling | 도메인 전문가와의 협업 시 | 사용 시나리오 중심으로 명확한 커뮤니케이션 |
Bounded Context Canvas | 컨텍스트 설계 및 책임 분리 시 | 컨텍스트 내 책임, 언어, 인터페이스 정리 |
Context Mapping Workshop | 전체 시스템 관계 설정 시 | BC 간 관계 및 통합 방식 명확화 |
Event Storming: 드론 배송 프로세스
|
|
Domain Storytelling: 드론 배송 시나리오
|
|
Bounded Context Canvas: 배송 관리 (Delivery Management)
|
|
Context Mapping Workshop: 전체 드론 배송 시스템
|
|
장점
카테고리 | 항목 | 설명 | 관련 개념 |
---|---|---|---|
아키텍처 및 구조 | 도메인 분리 | Bounded Context 기반으로 도메인을 명확히 분할 | Bounded Context |
복잡도 관리 | 시스템을 컨텍스트 단위로 나누어 복잡성을 제어 | Context Map | |
모델 무결성 유지 | 각 컨텍스트 내 일관된 모델 설계 가능 | 도메인 모델, 언어 정합성 | |
경계 기반 통제 | 명확한 경계로 도메인 간 혼합 방지 및 책임 분리 | Context Boundary | |
개발 및 운영 효율 | 독립 배포 및 확장 용이 | 각 컨텍스트는 독립적으로 배포 및 확장 가능 | Microservice-Friendly |
변화 대응력 향상 | 컨텍스트 경계로 변경 범위를 제한하여 유연성 확보 | Evolutionary Design | |
기술 선택 유연성 | 각 BC 마다 최적의 기술 스택 선택 가능 | Polyglot Architecture | |
유지보수성 향상 | 모듈화로 인해 코드 관리 및 확장 용이 | 도메인 중심 모듈 구성 | |
의존성 최소화 | 도메인 간 강결합 방지로 의존성 관리 가능 | 경계 분리 설계 | |
비즈니스 전략 및 정렬 | 비즈니스 정렬 | 도메인 구조가 비즈니스 전략과 직접 연결됨 | Core Domain 중심 설계 |
자원 집중 | 중요 도메인 (Core) 에 우선적으로 역량 및 인력 배치 | 도메인 우선순위 | |
비즈니스 이해도 향상 | 도메인 전문가와 협업을 통해 도메인 지식 내재화 | Event Storming, Storytelling | |
변화 영향 최소화 | 외부 시스템 변화에도 내부 모델을 보호 가능 | Anti-Corruption Layer | |
팀 및 협업 효율화 | 조직 구조와 아키텍처 정렬 | 팀 경계와 시스템 경계를 일치시켜 책임 명확화 | Conway’s Law 정렬 |
팀 자율성 확보 | 컨텍스트 단위로 팀의 독립성과 책임 분리 | BC 단위 팀 운영 | |
협업 강화 | 도메인별 팀 구성으로 커뮤니케이션 명확화 | 분리된 팀 책임 | |
언어 기반 소통 효율화 | Ubiquitous Language 로 소통 장애 제거 | 도메인 언어 정합성 | |
UX 및 품질 향상 | 비즈니스 용어의 코드 반영 | 실제 도메인 용어가 코드에 반영되어 이해도 향상 | 모델 ↔ 코드 일치 |
품질 향상 | 정확한 모델 기반 개발로 오류 가능성 감소 | 정합성 있는 설계 기반 | |
고객 중심 UX 설계 가능 | 도메인 중심 분석이 사용자 여정 기반 설계로 확장 | Problem Space 기반 설계 |
단점과 문제점 그리고 해결방안
단점
카테고리 | 항목 | 설명 | 해결책 |
---|---|---|---|
복잡성/비용 | 초기 설계 및 분석 부담 | 도메인 분석, Bounded Context 식별 등으로 프로젝트 초기 진입 장벽 증가 | 점진적 적용, MVP 기반 설계, 핵심 도메인 우선 도입 |
높은 초기 투자 비용 | 전략 워크숍, 교육, 도구 도입 등에서 발생하는 시간 및 인력 비용 | 단계적 예산 편성, 장기 ROI 관점 접근 | |
조직/운영 | 도메인 전문가 의존성 | 효과적 설계를 위해 도메인 전문가의 지속적 참여가 필수 | 도메인 전문가 사전 확보, 지식 정제 문서화 체계 구축 |
조직 구조와 연동 필요성 | 팀 구조와 컨텍스트 설계가 일치하지 않으면 책임 분산 및 소통 장애 발생 | Conway’s Law 정렬, 컨텍스트별 팀 책임 명확화 | |
학습/문화 | 학습 곡선 | 팀 전체가 DDD 개념, 전략/전술 패턴에 익숙해져야 효과적 설계 가능 | 사내 교육, 워크숍, 이벤트 스토밍, BDD 기반 문서 자동화 |
문제점
카테고리 | 문제 항목 | 원인 | 영향 | 탐지 및 진단 | 예방 방안 | 해결 방법 및 기법 |
---|---|---|---|---|---|---|
설계 문제 | 잘못된 경계 설정 | 도메인 이해 부족, 경계 성급한 결정 | 강결합, 모델 오염, 컨텍스트 사이 통신 증가 | 데이터 중복, 컨텍스트 간 API 난립 | 도메인 모델링 강화, Event Storming 반복 적용 | Context Map 재작성, 경계 재설정 |
컨텍스트 팽창 | 명확하지 않은 책임 구분, 기능 증가로 경계 확장됨 | 관심사 혼합, 응집도 저하 | 컨텍스트 크기 증가, 다양한 역할 혼재 감지 | 책임 기준 강화, 기능 추가 전 설계 검토 | 컨텍스트 분리, 새로운 BC 정의 | |
Context Drift | 설계 이후 문서 및 코드 반영 누락, 유지 부실 | 실제 경계와 설계 경계 불일치 → 혼란 및 오류 증가 | 코드 리뷰, 문서 - 구현 불일치 검토 | 정기적인 Context Map 리뷰 | 문서/모델 업데이트, 리팩토링 적용 | |
통합 문제 | 통합 비용 증가 | ACL, 메시징 등 통합 패턴 남용 | 시스템 복잡도, 성능 저하 | 네트워크 호출 횟수 증가, 트랜잭션 지연 추적 | 통합 우선순위 조정, 경량화 전략 수립 | 캐시 도입, 동기→비동기 전환 |
과도한 분산 | 마이크로서비스 도입 시 과도한 경계 분할 | 오버헤드 증가, 배포/운영 복잡성 | 호출 트레이싱, 배포 횟수 증가 감지 | 핵심 도메인 중심의 서비스 정의 | 컨텍스트 병합, 모듈화 (Monolith) 전환 고려 | |
협업 문제 | 언어 불일치 | 팀 간 소통 미흡, Ubiquitous Language 관리 부재 | 구현 오류, 명세 불일치 | 코드/문서/회의에서 용어 불일치 감지 | 용어집 관리 도구, 정기 용어 워크숍 운영 | 사전/코드 일치화, 공통 언어 정기 업데이트 |
유비쿼터스 언어 분절 | 코드/테스트/문서 간 언어 일관성 부족 | 커뮤니케이션 혼란, 요구 누락 | 충돌 단어 탐지, 회의 기록 분석 | 도메인 언어 사전 구축, BDD 기반 테스트 도입 | Domain Storytelling, 용어 리뷰 주기화 |
도전 과제
카테고리 | 도전 과제 | 원인 | 영향 | 탐지 및 진단 | 예방 방법 | 해결 방법 및 기법 |
---|---|---|---|---|---|---|
모듈화 및 독립성 | 경계와 팀 매핑 불일치 | 조직 구조와 도메인 모델 분리 | 개발 병목, 책임 불분명 | 코드 영역 분석, 소유권 추적 | 조직 - 도메인 구조 정렬 검토 | Bounded Context 재설정, 팀 재정렬 |
기술적 복잡도 | 경계 해결 정책 부재 | ACL, 공유 모델 등 통합 전략 미흡 | 통합 실패, 응답 지연 | 실패 로그, API 오류율 | 인터페이스 계약 문서화 | 중계 레이어 도입, 메시지 버전 관리 |
운영 및 유지관리 | 컨텍스트 간 데이터 흐름 지연 | 비동기 메시징 설계 난이도 | 실시간 연동 실패, 데이터 불일치 | 메시지 대기 시간, DLQ 모니터링 | 오류 리커버리 플로우 설계 | Retry 정책, Dead Letter Queue 도입 |
보안 및 규제 | 경계 간 인증/권한 관리 미흡 | 컨텍스트별 인증 정책 부재 | 보안 침해, 개인정보 유출 위험 | 인증 실패 로그, 권한 오남용 기록 | 통합 인증 전략, 최소 권한 원칙 | OAuth2, API Gateway 권한 제어 |
분산 시스템 설계 | 분산 시스템 복잡성 증가 | MSA 도입에 따른 운영 오버헤드 | 네트워크 지연, 부분 실패 | 분산 추적, 장애 분포 로그 | 적절한 경계 크기 유지 | Circuit Breaker, Saga, Event Sourcing |
데이터 일관성 | 데이터 동기화 어려움 | 컨텍스트 간 데이터 분산 | 데이터 불일치, 규칙 위반 | 데이터 품질 지표, 동기 실패 로그 | Eventually Consistent 설계 | CQRS, Saga, 보상 트랜잭션 설계 |
조직 정렬 | Conway’s Law 미적용 | 팀 구조가 시스템 경계 반영 못함 | 불필요한 의존성, 복잡한 경계 | 팀 간 소통 경로 분석 | 역 Conway 전략 적용 | 조직 개편, 크로스 펑셔널 팀 구성 |
레거시 통합 | 기존 시스템과 괴리 | 모놀리식 ↔ BC 간 통합 구조 부재 | 기술 부채 누적, 마이그레이션 지연 | 시스템 결합도 분석 | Strangler Fig 패턴 도입 | ACL, API Gateway, 인터페이스 분리 |
협업 및 언어 정합성 | 유비쿼터스 언어 분절 | 팀 간 도메인 언어 불일치 | 커뮤니케이션 오류, 요구 반영 실패 | 용어 충돌 탐지, 회의 기록 분석 | 정기 워크숍, 용어 문서 자동화 | Domain Storytelling, BDD 테스트 도입 |
분류 기준에 따른 종류 및 유형
분류 기준 | 유형 / 종류 | 설명 | 주요 특징 / 활용 목적 |
---|---|---|---|
도메인 중요도 | Core Domain | 비즈니스 핵심 가치/경쟁력을 제공하는 영역 | 최고 품질, 고비용 투자, 도메인 전문가 집중 |
Supporting Domain | Core Domain 을 지원하는 도메인 | 중요도 중간, 유연한 설계 가능 | |
Generic Domain | 범용적, 표준화된 기능 제공 도메인 | 외부 솔루션 대체 가능, 비즈니스 차별성 없음 | |
Bounded Context 관계 | Partnership | 두 컨텍스트가 동등한 협력자 관계 | 양방향 협력, 공동 책임, 긴밀한 소통 필요 |
Customer–Supplier | 상하류 모델 구조, 공급자 - 소비자 관계 | API 기반 통합, 의존성 방향 명확 | |
Conformist | 하위 컨텍스트가 상위 모델을 그대로 수용 | 통합 용이하나 유연성 부족, 하위 도메인의 유연성 제한 | |
Anti-Corruption Layer (ACL) | 외부 시스템 또는 상위 모델의 변경으로부터 내부 보호 | 번역 계층 도입, 모델 오염 방지 | |
Open Host Service | 외부와의 통합을 위해 공개된 API 나 인터페이스 제공 | 명확한 계약 기반 통신, 외부 소비자와의 상호작용 지원 | |
Published Language | 여러 컨텍스트가 공유하는 명세 기반 공통 언어 정의 | 통합 용이, 표준 메시지 포맷 사용 | |
Shared Kernel | 특정 모델의 일부를 소규모로 공유 | 강한 협력 기반, 변경 시 상호 영향 가능성 존재 | |
Separate Ways | 각 컨텍스트가 완전히 독립적으로 운영됨 | 의존성 제거, 중복 구현 허용, 유지보수 유리 | |
모델링 기법 | Event Storming | 도메인 이벤트 중심의 협업적 모델링 기법 | 빠른 도메인 흐름 파악, Bounded Context 식별 |
Domain Storytelling | 액터와 활동 중심의 스토리 기반 도메인 모델링 | 도메인 프로세스 내러티브 표현, 도메인 전문가 중심 | |
Bounded Context Canvas | Bounded Context 설계의 구조화된 템플릿 도구 | 책임, 인터페이스, 팀, 언어 등을 체계적으로 정의 | |
아키텍처 구현 방식 | Monolith | 단일 애플리케이션 구조 | 초기 설계 용이, 경계 혼합 위험 있음 |
Modular Monolith | 내부적으로 BC 기준 분할된 모놀리식 구조 | 점진적 전환 가능, MSA 이행 준비 단계 | |
Microservices Architecture | 각 컨텍스트 단위를 독립 서비스로 구현한 구조 | 독립 배포, 기술 선택 자유도, 조직 - 아키텍처 정렬 필수 | |
통합 및 통신 방식 | REST / API 기반 통신 | 동기 방식의 서비스 간 호출 | 빠른 응답, 명확한 계약, 통합 단순 |
Messaging / Event 기반 통신 | 비동기 이벤트 기반 통합 | 느슨한 결합, 확장성 및 복원력 강화 | |
Shared DB / Data Sharing | 동일 DB 또는 데이터 구조 공유 | 빠른 통합 가능하지만 결합도 높음, 권장되지 않음 |
실무 사용 예시
📁 카테고리 | 🛠️ 함께 사용하는 기술/방법 | 🎯 주요 목적 | 💡 기대 효과 |
---|---|---|---|
1. 서비스 경계 정의 및 분리 | Bounded Context + API Gateway Microservices + Context Mapping Context Map | 서비스 독립화, 명확한 경계 설정 | 독립 배포, 팀 중심 개발, 유지보수 용이성, 경계 명확화 |
2. 도메인 설계 및 탐색 | Event Storming Domain Storytelling Shared Language | 도메인 모델 발굴, 도메인 전문가와 협업 | 빠른 피드백, 반복적 개선, 개발자 - 도메인 전문가 소통 강화 |
3. 핵심 도메인 최적화 | CQRS + Core Subdomain Bounded Context + CQRS Ubiquitous Language | 성능 분리, 복잡성 관리, 읽기/쓰기 모델 분리 | 핵심 도메인 경량화, 성능 최적화, 복잡도 국한 |
4. 공통 기능 공유 및 통합 | Shared Kernel ACL (Anti-Corruption Layer) | 중복 제거, 이질 시스템 간 통합 | 통합 비용 절감, 모델 일관성 확보, 버전 호환 유연화 |
5. 개발 조직 정렬 | Context-Team Alignment Bounded Context | 조직 구조와 도메인 구조 정렬 | 팀 책임 명확화, 배포 독립성 향상 |
6. 의존성 및 유지보수 관리 | Bounded Context + API Separate Ways | 코드 및 시스템 간 결합도 최소화 | 유지보수성 향상, 느슨한 결합 |
7. 인프라 및 배포 전략 | DevOps 파이프라인 Context Map 기반 독립 배포 | 컨텍스트별 CI/CD, 안정적인 운영 | 배포 자동화, 배포 속도 향상, 실패 격리 가능 |
8. 확장성과 유연성 확보 | 마이크로서비스 + 모듈화 클라우드 네이티브 아키텍처 | 확장 가능하고 유연한 구조 설계 | 자원 효율성, 독립적 확장, 고가용성 구조 확보 |
- Bounded Context는 거의 모든 카테고리에 걸쳐 핵심 기반으로 사용됨.
- Context Map은 서비스 정의, 팀 정렬, 배포 전략 등 다방면에서 활용됨.
- Event Storming은 설계 초기와 반복적 개선 과정에서 강력한 도구로 작동함.
활용 사례
사례 1: 전자상거래 플랫폼 구축 사례
시스템 구성:
- Order Management Context: 주문 처리 및 상태 관리
- Inventory Context: 재고 관리 및 가용성 확인
- Payment Context: 결제 처리 및 검증
- Shipping Context: 배송 관리 및 추적
- Customer Context: 고객 정보 및 프로필 관리
시스템 구성 다이어그램:
graph TB subgraph "Customer Experience" Web[Web Frontend] Mobile[Mobile App] end subgraph "Core Business Contexts" OM[Order Management] INV[Inventory] PAY[Payment] SHIP[Shipping] CUST[Customer] end subgraph "Supporting Contexts" NOT[Notification] REP[Reporting] AUTH[Authentication] end Web --> OM Mobile --> OM OM --> INV OM --> PAY OM --> SHIP OM --> CUST OM --> NOT INV -.->|Events| REP PAY -.->|Events| REP SHIP -.->|Events| REP
활용 워크플로:
도메인 분석 단계
- EventStorming 을 통한 주문 프로세스 모델링
- 도메인 전문가와 핵심 이벤트 식별
- 하위 도메인 분류 (Core: 주문, Supporting: 재고/배송, Generic: 인증)
Bounded Context 설계
- 각 컨텍스트의 Ubiquitous Language 정의
- 컨텍스트 간 통합 패턴 선택
- Anti-Corruption Layer 설계
Context Mapping
- Order → Inventory: Customer-Supplier 관계
- Order → Payment: Partnership 관계
- Order → Shipping: Customer-Supplier 관계
Strategic Design 의 역할:
- 복잡성 관리: 대규모 전자상거래 도메인을 관리 가능한 컨텍스트로 분해
- 팀 자율성: 각 컨텍스트별 독립적인 개발팀 구성
- 비즈니스 정렬: Core Domain(주문 처리) 에 최고 품질 팀 배정
- 변화 대응: 새로운 비즈니스 요구사항에 대한 영향 범위 제한
사례 2: 이커머스 주문처리 시스템
시스템 구성 및 워크플로우:
graph LR subgraph Catalog_BC CatalogAPI end subgraph Order_BC OrderAPI end subgraph Payment_BC PaymentAPI end Catalog_BC -->|ACL| Order_BC Order_BC -->|Customer–Supplier| Payment_BC
Workflow
- 카탈로그 BC: 제품 조회
- 주문 BC: 주문 생성 시 카탈로그에서 ACL 통해 데이터 조회
- 결제 BC: 주문 BC 가 고객으로서 결제 요청
- BC 간 명확한 경계와 계약 기반 통합
구현 예시
Strategic Design 패턴을 활용한 전자상거래 시스템 구현
- Bounded Context: Order Management 와 Inventory Management 로 명확히 구분
- Ubiquitous Language: 각 컨텍스트에서 도메인 특화 용어 사용
- Domain Events: 컨텍스트 간 느슨한 결합 통신
- Context Integration: Customer-Supplier 패턴 구현
- Anti-Corruption Layer: 외부 시스템과의 안전한 통합
|
|
실무에서 효과적으로 적용하기 위한 고려사항 및 주의할 점
카테고리 | 핵심 고려사항 | 설명 | 권장 사항 / 실천 방법 |
---|---|---|---|
도메인 분석 | 도메인 경계 명확화 | Bounded Context 를 기준으로 비즈니스 도메인을 구체적으로 구분 | Event Storming, Domain Storytelling 활용 |
도메인 지식 확보 | 깊이 있는 비즈니스 이해 없이는 도메인 모델 설계 불가 | 도메인 전문가와 정기 협업, 인터뷰, Shadowing | |
공유 언어 (Ubiquitous Language) | 도메인 내의 모든 구성원이 동일한 용어를 사용해야 일관된 모델 유지 가능 | 용어 사전 작성 및 주기적 업데이트, 문서화 프로세스 포함 | |
조직 및 팀 구조 | 컨텍스트 중심 팀 구성 | Bounded Context 단위로 팀을 분리하여 자율적 운영 체계 구축 | 크로스 펑셔널 팀 구성, 팀 간 인터페이스 명확화 |
책임/권한 분리 | 각 컨텍스트별 소유자 명확히 정의, 업무 충돌 방지 | 팀별 명세 관리 책임 설정, 리더 지정 | |
적용 전략 | 점진적 적용 | 시스템 전체를 한 번에 DDD 로 전환하면 리스크 큼 | Core Domain 중심 MVP 구축 → 점진적 확장 |
컨텍스트 크기 조절 | 너무 작거나 크면 유지보수 어려움 | Conway 의 법칙 고려하여 팀 규모와 연계, Context Map 활용 | |
기술 및 통합 전략 | 통합 전략 설계 | 컨텍스트 간 통신 및 데이터 흐름 정의 필요 | OHS, ACL, Customer-Supplier 등 적절한 통합 패턴 적용 |
API 및 이벤트 계약 관리 | API/이벤트는 명시적 계약 기반이어야 함 | OpenAPI, Schema Registry, 버전 관리 정책 수립 | |
기술 스택 최적화 | 각 도메인의 특성과 목적에 따라 기술을 선택해야 유연성 확보 | CQRS, Event Sourcing, RDB/NoSQL 등 도메인 중심 기술 선택 | |
도구 및 프로세스 | 도구 활용 | 효과적인 커뮤니케이션과 모델링을 위한 도구 필요 | Miro, Context Mapper, EventStorming 툴 등 실습 기반 도입 |
문서화 및 지속적 관리 | 모델/용어/계약은 지속적으로 진화하며 관리되어야 함 | 자동화된 문서화 (Swagger, Markdown), 정기 리뷰 회의 | |
조직 문화 | 협업 문화 구축 | 도메인 중심의 설계는 팀 간 소통이 핵심 | 정기 미팅, 리뷰 문화, 공동 워크숍 및 리더십 참여 |
변화 수용과 학습 | 도입 과정에서 발생하는 불확실성과 조직 저항에 대한 유연한 대응 | 실패 수용, 실험적 전환, 사내 DDD 학습 커뮤니티 운영 |
최적화하기 위한 고려사항 및 주의할 점
카테고리 | 고려사항/이슈 | 설명 | 실무 권장사항 |
---|---|---|---|
경계 설계 | 경계 (Bounded Context) 재조정 필요 | 초기 정의된 컨텍스트가 현실과 맞지 않거나 지나치게 작거나 클 수 있음 | 핵심 서브도메인부터 시작해 점진적으로 확장. 정기적 Event Storming 워크숍 수행 |
통신 최적화 | 과도한 동기 호출 지양 | RESTful API 중심 구조는 컨텍스트 간 통신 병목 유발 가능 | 이벤트 기반 아키텍처 (Event-Driven), 비동기 메시징 (RabbitMQ/Kafka) 활용 |
데이터 일관성 | 데이터 동기화 문제 | 비동기 환경에서 데이터 불일치 발생 가능 (예: 주문 상태 vs 결제 상태) | Saga 패턴, 보상 트랜잭션, Eventually Consistent 모델 설계 |
의존성 관리 | 컨텍스트 간 강결합 발생 | Shared Kernel, Conformist 등은 유지보수 비용 증가 위험 존재 | API 계약 기반 설계, ACL 도입, 명시적 Published Language 정의 |
배포 및 운영 | 독립 배포 어려움 | 컨텍스트 간 코드 공유, 상태 공유 시 단일 배포 강제될 수 있음 | 컨텍스트별 CI/CD 구성, Blue-Green/Canary 배포 전략, Feature Flag 활용 |
보안 전략 | 인증/인가 체계 통합 미비 | 컨텍스트별 보안 요구사항 다르며, 일괄 적용이 어려움 | API Gateway 에서 인증/인가 처리, OAuth2, JWT 기반 인증 연동 |
관측 가능성 | 장애 추적 및 진단 어려움 | 분산된 컨텍스트 환경에서 문제 지점 파악이 어려움 | OpenTelemetry, Zipkin, Prometheus 등으로 통합 로깅 및 추적 시스템 구성 |
테스트 전략 | 통합 테스트 어려움 | 컨텍스트 간 메시지 기반 통신 시 테스트 복잡도 증가 | Contract Testing(Pact 등), Consumer-Driven Test, Integration Test 분리 |
기술 확장성 | 컨텍스트마다 기술 이질성 존재 | 서로 다른 기술 스택과 설계 기준 사용 시 통합 복잡도 상승 | 표준화된 메시지 포맷 사용 (Protobuf, Avro), ContextMapper 등으로 구조 자동화 |
변경 관리 체계 | 모델 또는 API 변경 혼선 | Upstream 의 변경이 Downstream 에 급격한 영향 | 버전 관리 (V1/V2), 구형 모델 호환 어댑터 제공, 변경 알림 시스템 구축 |
도구 활용 | 수동 설계의 한계 | Bounded Context, Context Map 관리에 시간이 소요됨 | Context Mapping → ArchUnit, ContextMapper 등 코드 자동화 도구 활용 |
성능 최적화 | 처리 지연 및 과부하 발생 | 트래픽 집중 BC 또는 병목이 발생할 수 있음 | Bulk API, 캐싱 전략 (Redis), 오토 스케일링 (HPA) 도입 |
주제와 관련하여 주목할 내용
구분 | 카테고리 | 항목 | 설명 |
---|---|---|---|
핵심 개념 | 도메인 구조 | Bounded Context | 도메인 모델이 유효한 경계를 정의하고, 해당 범위 내 일관된 설계를 유지함. |
하위 도메인 분리 | Core, Supporting, Generic | 비즈니스 중심 가치 기준으로 도메인을 분류하여 설계/투자 우선순위 결정 가능. | |
공유 언어 (Ubiquitous Language) | 도메인 공통 언어 사용 | 팀 간 용어 불일치 제거, 모델 - 코드 - 커뮤니케이션 간 정렬 확보. | |
방법론 | 협업 기반 모델링 기법 | EventStorming | 도메인 이벤트를 중심으로 시각적으로 프로세스를 모델링하는 협업 기법. |
Domain Storytelling | 액터 중심의 도메인 스토리 플로우를 통해 사용자와 시스템의 상호작용을 명확화. | ||
설계 도구 | 모델링 도구 | Context Mapper | Context Map, Bounded Context 설계를 위한 시각화 및 관리 도구. |
Bounded Context Canvas | 컨텍스트의 이름, 책임, 인터페이스, 모델 등을 명확히 문서화하는 캔버스 템플릿. | ||
패턴 | 컨텍스트 통합 전략 | Shared Kernel | 공통 모델 공유, 철저한 협업 필요. 공통 계약/모델에 대한 양측 책임 공유. |
ACL (Anti-Corruption Layer) | 번역 계층으로 외부 시스템과의 간접 통합, 도메인 모델 보호. | ||
Customer-Supplier | 소비자 (Downstream) 가 공급자 (Upstream) 와의 계약에 따라 모델을 수용. | ||
Conformist | 외부 API/모델을 그대로 수용, 유연성보다 일관성을 우선시. | ||
Separate Ways | 완전한 모델 분리로 통합 최소화. 각 도메인이 독립적으로 진화. | ||
아키텍처 | 레이어 구조 | Hexagonal Architecture | 포트 - 어댑터 기반. 도메인을 외부로부터 격리하고, 입출력을 유연하게 관리. |
Onion Architecture | 내부 도메인 중심의 계층 구성. 의존성은 안쪽으로 향하고 외부는 도메인에 의존. | ||
데이터 전략 | 상태 및 이벤트 처리 | Event Sourcing | 상태 저장 대신 이벤트 시퀀스를 저장하여 변경 추적, 재구성 가능. |
CQRS (Command Query Responsibility Segregation) | 명령 (쓰기) 과 조회 (읽기) 모델 분리로 성능 최적화. | ||
Database per Service | 각 서비스마다 독립된 DB 를 보유. 서비스 간 강결합 방지 및 장애 전파 최소화. | ||
사례 및 적용 | 조직/사례 전략 | Elixir University 사례 | Bounded Context 분리, 컨텍스트 매핑 사례로 실전 적용 기반 제공. |
조직 구조 | Conway’s Law | 조직 구조가 소프트웨어 구조에 영향을 주므로, 팀 구성과 도메인 정렬이 필요함. | |
점진적 전환 | Strangler Fig Pattern | 레거시를 유지하며 신규 시스템을 점진적으로 도입해 전체 전환 유도. | |
워크숍/실행 | 협업 기반 실행 전략 | Context Mapping Workshop | 여러 BC 간의 관계를 시각화하고, 통합 전략을 명확히 설계하는 공동 워크숍. |
용어 정리/사전 작성 | 도메인 용어의 일관성 확보 및 팀 간 커뮤니케이션 효율화. |
주제와 관련하여 반드시 학습해야할 내용
구분 | 카테고리 | 주제 | 항목 | 설명 |
---|---|---|---|---|
핵심 개념 | 도메인 주도 설계 | Domain-Driven Design (DDD) | 전체 개요 | Strategic + Tactical Design 모두 포함하는 도메인 중심 설계 방법론의 전반적 이해 |
Bounded Context | 경계 컨텍스트 정의 | 도메인 모델이 유효한 경계를 갖는 설계 단위. 마이크로서비스 분해의 기준이 됨. | ||
Ubiquitous Language | 공유 언어 | 비즈니스와 개발팀 간 언어 일치. 모델, 코드, 문서, 커뮤니케이션을 정렬시키는 핵심 요소 | ||
Context Map | 컨텍스트 맵핑 | 여러 Bounded Context 간 관계, 통합 전략, 방향성 (Upstream/Downstream) 을 시각화 | ||
설계 기법 | 도메인 설계 기법 | Domain Modeling | 도메인 객체, 엔티티, 밸류, 애그리거트 설계 | 도메인 로직을 표현하는 전반적인 설계 기술. Tactical Design 과 직접 연결됨. |
Aggregate Pattern | 일관성 경계 | 트랜잭션 경계와 도메인 객체 집합의 경계를 정의하여 무결성을 보장함. | ||
Integration Patterns | 컨텍스트 통합 전략 | Shared Kernel, ACL, OHS 등 전략에 따라 BC 간 통신/통합 방식 결정됨. | ||
아키텍처 | 시스템 설계 구조 | Microservices Architecture | Bounded Context 기반 분해 | BC 를 기준으로 마이크로서비스 분할, 독립 배포/개발/확장성 확보 |
Event-Driven Architecture | 느슨한 결합 구조 | 이벤트 발행 - 구독 모델 기반의 비동기 메시징 구조. 통합 지연 및 실패 대응에 유리 | ||
Database per Service | 데이터 분리 전략 | 각 서비스의 독립적인 데이터 저장소 운영, 스키마 충돌/의존도 최소화 | ||
조직 전략 | 협업 및 정렬 전략 | Team Topologies | 팀 구조와 아키텍처 정렬 | 조직 구조 (스트림 얼라인드 팀 등) 와 설계 구조 (BC) 간의 정렬로 생산성과 속도 향상 |
Conway’s Law | 조직 구조 = 시스템 구조 | 조직의 커뮤니케이션 구조가 시스템 구조를 결정한다는 설계 원칙 | ||
적용 방법 | 도구 및 실천 전략 | EventStorming | 협업 모델링 도구 | 도메인 이벤트 중심의 시각적 모델링. 컨텍스트 정의 및 도메인 흐름 분석에 유리 |
Context Mapping Workshop | 관계 정의 워크숍 | 여러 BC 간의 관계를 정의하고, 통합 패턴 적용 및 설계 합의를 위한 협업적 분석 방식 | ||
Bounded Context Canvas | 컨텍스트 문서화 도구 | 목적, 책임, 인터페이스, 언어 등을 명시적으로 정리하여 팀 간 설계 일관성을 확보 |
용어 정리
카테고리 | 용어 | 설명 |
---|---|---|
핵심 개념 | Domain-Driven Design (DDD) | 복잡한 도메인 문제 해결을 위한 모델 기반 소프트웨어 설계 접근법 |
Strategic Design (전략적 설계) | 도메인 분리, Bounded Context 정의, 컨텍스트 간 관계 설계 중심 | |
Tactical Design (전술적 설계) | Entity, Value Object, Aggregate 등 구현 중심의 설계 구성 요소 | |
도메인 구조 | Domain (도메인) | 비즈니스 문제와 규칙이 존재하는 문제 공간 |
Subdomain (하위 도메인) | 도메인을 Core, Supporting, Generic 으로 세분화한 단위 | |
Problem Space (문제 공간) | 고객 가치와 비즈니스 문제 정의 영역 | |
Solution Space (해결 공간) | 소프트웨어로 문제를 해결하는 설계 및 구현 공간 | |
경계 및 모델 | Bounded Context (경계 컨텍스트) | 특정 도메인 모델이 일관성 있게 적용되는 명확한 책임 경계 단위 |
Context Map (컨텍스트 맵) | Bounded Context 간 관계 및 통합 전략을 시각화한 다이어그램 | |
Ubiquitous Language (공통 언어) | 도메인 전문가와 개발자가 공유하는 일관된 용어 체계 | |
통합 패턴 | Shared Kernel (공유 커널) | 두 컨텍스트 간 일부 모델을 신중하게 공유하는 전략 |
Customer–Supplier (고객–공급자) | Upstream(공급자) 와 Downstream(소비자) 간 명확한 역할 기반 통합 패턴 | |
Conformist (순응자) | Downstream 이 Upstream 의 모델/계약을 그대로 수용하는 패턴 | |
Open Host Service (공개 호스트 서비스) | 외부 접근을 위한 표준화된 API/이벤트 인터페이스를 제공하는 패턴 | |
Published Language (공개 언어) | 컨텍스트 간 메시지 교환을 위한 표준 스키마 및 언어 정의 | |
Anti-Corruption Layer (ACL) | 외부 모델로부터의 오염 방지를 위해 변환 계층을 두는 보호 전략 | |
Partnership (파트너십) | 두 컨텍스트가 공동 목표를 위해 협력하고 모델/계약을 공동 관리하는 관계 | |
Separate Ways (독립 진화) | 통합 없이 각자 독립적으로 발전하는 선택적 분리 전략 | |
설계 기법 | EventStorming | 도메인 이벤트를 중심으로 도메인 흐름을 시각화하는 협업 모델링 기법 |
Domain Storytelling | 도메인 워크플로우를 스토리 기반으로 시각화하는 분석 기법 | |
설계 도구 | Bounded Context Canvas | Bounded Context 를 구조적으로 정의하기 위한 템플릿 도구 |
Context Mapper | Context Map 및 관계 모델링을 위한 도구 | |
아키텍처 원칙 | Conway’s Law (컨웨이 법칙) | 조직 구조가 시스템 아키텍처에 직접적인 영향을 준다는 법칙 |
Inverse Conway Maneuver (역전 전략) | 원하는 아키텍처를 달성하기 위해 조직 구조를 먼저 설계하는 전략 | |
아키텍처 패턴 | Microservices Architecture | Bounded Context 를 독립 마이크로서비스로 분해하는 설계 스타일 |
Hexagonal Architecture | 도메인 로직을 어댑터/포트를 통해 외부와 분리하는 계층형 아키텍처 | |
Onion Architecture | 도메인 중심의 계층 구조로, 의존성 역전 원칙을 강조 | |
설계 기법 | Event Sourcing | 상태 변화를 이벤트로 저장하여 재구성하는 상태 관리 기법 |
CQRS (Command Query Responsibility Segregation) | 명령과 조회를 분리하여 성능과 확장성을 최적화하는 패턴 |
참고 및 출처
핵심 문헌
- Domain-Driven Design: Tackling Complexity in the Heart of Software–Eric Evans 의 DDD 원서
- Implementing Domain-Driven Design–Vaughn Vernon 의 실무 지침서
- Learning Domain-Driven Design–Vlad Khononov 저, O’Reilly 출판의 입문서
온라인 리소스
개념 및 설계 설명
- Domain-Driven Design (Bliki)–Martin Fowler 의 설명
- Domain-Driven Design (Wikipedia)–위키백과 개요
- Strategic Design in DDD–DevIQ 의 전략 설계 설명
- Domain-Driven Design (DDD): Strategic Design Explained–Medium 아티클
전략적 설계 심화
- Strategic Domain-Driven Design with Context Mapping–InfoQ 의 컨텍스트 매핑 설명
- DDD Part 1: Strategic Domain‑Driven Design–Vaadin 블로그
- A Hitchhiker’s Guide to Strategic Design–HYR.MN 블로그 가이드
실무 도구 및 플랫폼
- Context Mapper–Context Map 설계 및 시각화 도구
- EventStorming–Alberto Brandolini 의 협업적 도메인 모델링
- Domain Storytelling–스토리 기반 도메인 설계 방법론
- Bounded Context Canvas–Nick Tune 이 설계한 캔버스 템플릿
커뮤니티 및 교육
- Domain-Driven Design Community–DDD 공식 커뮤니티
- DDD Academy–교육 자료 및 과정
- Virtual DDD–온라인 워크숍, 세미나 커뮤니티
- Awesome DDD–GitHub 기반 DDD 자료 모음
기술 블로그 및 사례 연구
- Domain Driven Design in 10 Minutes (Part One)–ThoughtWorks 블로그
- Using Tactical DDD to Design Microservices–Microsoft Azure Architecture Center
- Domain-Driven Design Fundamentals – Redis–Redis 공식 문서