Domain Driven Design : DDD
소프트웨어 개발의 복잡성을 해결하기 위한 설계 방법론
1. 비즈니스 Domain 별로 나누어 설계하는 방식
2. 핵심 목표 : "Loosly coupling", "High cohesion" - 모듈 간의 의존성 최소화 및 응집성 최대화
3. Strategic Design(개념 설계) / Tactical Design(구체적 설계)
특징
- 도메인의 모델과 로직에 집중 (데이터 중심 → 도메인 중심 접근)
- Ubiquitous Language : 보편적 언어 사용
: 여기서 말하는 언어는 개발자도 알고 도메인 전문가도 아는 언어 == 비즈니스 용어를 하나로 통합한 공통의 언어
※ 고려사항
- Bounded Context (제한 영역) 범위 내에서 정의
- 용어 사전 (Glossary) 형태로 구성하는 것 권장 (: 처음부터 모든 용어를 사전처럼 정의하고 진행하는 것 불가)
- Software Entity와 Domain 간의 개념 일치
- 전략적 설계 (Strategic Design)
: 복잡한 도메인의 경계를 상황(Context)에 맞게 명확히 정의하는 과정 (개념적 설계)
- 도메인 이해 관계자끼리 지식을 공유하고 이해 후 정의
- 개념과 경계를 식별하여 바운디드 컨텍스트로 정의
- 경계의 관계를 컨텍스트 맵으로 정의
- 전술적 설계 (Tactical Design)
: 전략적 설계를 통해 식별된 내부를 상세하게 설계하는 과정 (구체적 설계)
- 전략적 설계에서 도출된 바운디드 컨텍스트와 도메인을 이용해 *애그리거트 패턴, 엔티티와 값 객체, 레포지토리 등 구성 및 구현
| 설계 | 전략적 설계 | 전술적 설계 |
| 범위 | 전반적 | 특정 Bounded-Context |
| 목적 | 문제 도메인을 해결영역으로 | 풍부한 도메인 모델 적용 |
| 메타포 | 전쟁에서 전략 | 전투에서 전술 |
| 주요 패턴 | Bounded-Context, Ubiquitous-Language | Aggregate, Domain-Event |
| 수행 방식 | 접근법 | 상대적으로 방법론에 가까움 |
* Bounded Context (바운디드 컨텍스트) : 사용자 프로세스, 정책/규정 등을 고유한 비즈니스 목적별로 그룹화한 것
= 독립적으로 서비스될 때 문제가 없는 업무의 범위
* Context map (컨텍스트 맵) : 바운디드 컨텍스트 간의 관계를 도식화 한 것
* Aggregate (애그리거트) : 도메인 영역을 구성하는 요소 중 하나로, 관련된 도메인 객체들의 집합 - 즉 관련된 객체들을 모아 하나의 단위로 취급하는 개념 (아래에 더 자세하게 설명)
Domain(도메인)
- 지식 활동의 영역
- 사용자가 사용하는 것, 소프트웨어로 해결하고자 하는 문제 영역
- (프로그래머의 관점) 애플리케이션 내의 로직들이 관여하는 정보와 활동의 영역
- (DDD)관점 : 비즈니스 Domain
Domain Model (도메인 모델)
- 특정 도메인을 개념적으로 표현한 것
- 소프트웨어 기능과 데이터 구조를 비즈니스의 실제 운영과 일치 시키기 위해 사용
- 도메인 모델을 표현하는 다양한 방식(객체, 다이어그램, 그래프, 공식 등)
Domain Model Pattern (도메인 모델 패턴)
: 도메인 모델을 생성하는 패턴
구성요소
- Entity
- 고유의 식별자를 갖는 도메인 객체
- 자신의 상태와 라이프 사이클 가짐
- Value Object
- 고유한 식별자를 가지지 않는 불변 객체
- 식별성이 아닌 속성을 이용해 정의
- 불변성을 위해 setter 사용 지양
- Service
- 도메인 객체에 위치시키기 어려운 연산을 캡슐화하는 객체
- 일반적으로 상태를 갖지 않는 stateless
- 데이터를 직접 저장하거나 관리하지는 않고, 필요한 연산 수행 후 결과를 반환
- Module
- 유사 작업 및 개념을 그룹화하여 시스템 복잡도 감소시키는 설계 기법
→ JAVA의 경우 package를 사용하여 모듈 구현 : 응집도를 높이고 결합도를 낮추기 위함
- Aggregate
- 연관된 Entity와 Value Object(값 객체)를 하나로 묶은 군집
- 각각의 일관성을 보장하여 트랜잭션과 분산처리의 단위
- 개별 객체가 아닌 관련 객체를 하나로 묶어 객체 군집 단위로 모델을 볼 수 있게 함
+) 애그리거트 루트 Aggregate root
: 포함된 객체들의 대표, 하위 개념을 표현한 모델을 하나로 묶어야 할 핵심 도메인 기능을 보유하고 있는 모델
애그리거트 내에서 유일하게 외부와 상호작용할 수 있는 진입점(Entry Point)역할
- Factory
- Entity 객체의 생성에 관련된 복잡성을 캡슐화하는 설계 패턴
- 객체 생성의 전체 과정을 책임짐 → 객체 생성의 세부 사항을 걱정하지 않고, 일관된 방식으로 복잡한 객체 생성 가능
- Repository
- 도메인 영역과 데이터 infrastructure 계층 사이의 분리를 가능하게 하는 패턴
- 데이터 계층의 결합도를 낮추고 도메인 모델의 독립성 향상 → 시스템의 유연성, 확장성 증가
도메인 주도 설계 아키텍처
계층형 아키텍처 Layered Architecture
- User Interface (표현계층) : 사용자의 요청을 하위 레이어로 전달
- Application (응용계층) : 복잡한 비즈니스 로직 처리 (트랜잭션 처리 담당)
- Domain (도메인 계층): 도메인에 대한 정보, 객체 상태, 도메인의 비즈니스 로직 제공
- Infrastructure : 영속성을 구현하거나 외부와 통신하는 기능 제공 - 리포지토리 구현체, 파일 시스템 접근 등
- 도메인 계층에서 정의한 리포지토리 인터페이스를 구현하여 데이터베이스 접근을 처리
도메인 계층을 외부로 부터 보호하기 위해서, 도메인 계층이 인프라 계층에 의존하는 것을 막고자 의존성 역전 원칙 적용
* 의존성 역전 원칙 (Dependency Inversion Principle)
→ 고수준 모듈은 더이상 저수준 모듈에 의존하지 않고, 저수준 모듈은 구현 추상화한 인터페이스에 의존
추상화한 인터페이스는 저수준 모듈이 아닌 고수준 모듈에 위치
* 상위 계층이 하위 계층에 의존
Bounded Context
: 구분되는 경계를 갖는 컨텍스트
- 모델의 경계를 결정
- 한 개의 바운디드 컨텍스트는 논리적으로 한 개의 모델을 가짐
- 도메인 기능을 사용자에게 제공하는데 필요한 표현 영역, 응용 서비스, 도메인, 인프라스트럭처 영역, 테이블도 모두 포함
각각의 Context는 독립적으로 구현될 수 있으며, 통합이 필요하다
- 간접 통합 : 각 바운디드 컨텍스트가 독립성을 유지하면서 통합 (ex. 메세지 큐)
- 직접 통합 : 한 바운디드 컨텍스트가 다른 바운디드 컨텍스트의 내부 구현에 직접 접근하는 방식 (bad)
관계
- 상류, 하류 관계
: 한 쪽에서 데이터 제공(상류) , 다른 한 쪽에서는 데이터 호출 (하류)
하류에서 상류의 데이터를 받아서 사용할 때, *ACL을 만들어서 보호한다
- 공유 커널
: 두 바운디드 컨텍스트가 같은 모델을 공유하는 경우, 해당 서비스 모델을 공유함으로써 공통된 개발 막음
- 독립 방식
: 서로 통합하지 않고 모델을 발전시키는 방식
* anti-corruption layer (ACL - 부패 방지 계층)
- 레거시 시스템을 새로운 시스템으로 여러 단계에 걸처 이전할 때 사용할 수 있는 패턴
- 서로 다른 두 시스템이 망가지는 것을 방지하기 위해 사용하고 두 시스템 간의 원할한 서비스가 되도록 수행
[사용되는 상황]
○ 타 시스템 연계 (3rd party system)
○ 서로 다른 통신 프로토콜 사용 시
○ 서로 다른 도메인 모델 설계
○ 서로 다른 데이터 타입 사용
○ 서로 다른 플랫폼 인프라 계층의 연계
이벤트 스토밍 워크샵 - 업무 흐름을 이벤트 중심으로 매핑 (Bounded Context 식별)
컨텍스트 매핑
- 각 Context가 어떻게 협력하고, 데이터나 이벤트를 교환하며, 통합되는지를 시각적으로 표현함
컨텍스트 맵
: Bounded Context 간 관계 표시 (OHS: 오픈 호스트 서비스 / ACL: 안티 코럽션 계층)
컨텍스트 간 관계가 바뀔 경우 컨텍스트 맵도 변경됨
참고자료
Anti-Corruption Layer Pattern - Junhyunny’s Devlogs
Anti-Corruption Layer Pattern
<br /><br />
junhyunny.github.io