DDD
DDD는 복잡한 도메인을 명확히 표현하고, 비즈니스 규칙을 코드 구조의 중심에 두는 설계 방식이다. 구성은 크게 Presentation → Application → Domain → Infrastructure 계층으로 나뉜다.
DDD의 중요 개념
- 도메인(Domain): 소프트웨어가 해결하려는 비즈니스 영역이나 문제 공간.
- 유비쿼터스 언어(Ubiquitous Language): 팀 내 모든 구성원이 공통으로 사용하는 언어로, 도메인 모델과 소통을 일관되게 유지.
- 바운디드 컨텍스트(Bounded Context): 도메인을 여러 개의 독립된 컨텍스트로 분리하여 복잡성을 관리.
- 애그리거트(Aggregate): 도메인 모델 내에서 일관성을 유지해야 하는 객체들의 집합.
- 루트 애그리거트(Root Aggregate): 애그리거트의 진입점이 되는 핵심 엔티티.
- 벨류 오브젝트(Value Object): 식별자가 필요 없는 객체로, 속성만으로 식별됨.
- 엔티티(Entity): 고유한 식별자를 가지며, 지속적인 생명주기를 가진 도메인 객체.
1. Presentation Layer (UI 계층)
역할
- 사용자의 입력을 받고 결과를 반환
- Application Service를 호출하여 처리 흐름을 시작함
구성 요소
Controller - HTTP 요청/응답 처리 - DTO 매핑 - 비즈니스 로직 없음
DTO (Request / Response) - 계층 간 데이터 전달 객체 - 검증 및 단순 변환만 수행 - 도메인 지식 포함 X
2. Application Layer (애플리케이션 계층)
역할
- 유즈케이스(Use Case) 실행
- 도메인 객체를 조립하고 트랜잭션 경계를 관리
- 도메인 규칙은 포함하지 않음 (흐름만 제어)
구성 요소
Application Service - Controller → Application Service → Domain 객체 호출 흐름 구성 - 예: 주문 생성, 사용자 등록 프로세스 처리
Command / Query (옵션, CQRS 기반) - Command: 상태 변경 - Query: 데이터 조회
3. Domain Layer (도메인 계층)
역할
DDD의 핵심. 비즈니스 규칙, 모델, 정책을 모두 포함하며 어떤 기술에도 의존하지 않아야 함.
구성 요소
Entity - 고유 ID를 가지고 상태 + 행동을 가진 객체 - 예: Order, User
Value Object - 식별자 없음, 속성 기반 비교 - 불변성 유지 - 예: Money, Address
Aggregate & Aggregate Root - 불변성을 유지해야 하는 객체 그룹 - Root 외부에서는 내부 객체에 직접 접근 불가
Domain Service - 특정 Entity에 속하지 않는 도메인 규칙 처리 - 무상태(stateless)
Repository Interface - 도메인 계층에서 영속성 기술을 추상화한 인터페이스 선언
Domain Event - 도메인 내 의미 있는 사건 표현 (예: 주문 생성됨)
4. Infrastructure Layer (인프라 계층)
역할
- 기술적 구현부 (DB, Network, File, 외부 API 등)
구성 요소
Repository 구현체 - Repository 인터페이스의 실제 구현 - 예: JPA 기반 구현
외부 API 연동 - RestTemplate, WebClient 등 호출
설정 / 구성 요소 - ORM 설정 - 메시지 브로커, Redis, Kafka 등
전체 구조 요약 (디렉토리 예시)
presentation/
└─ controller/
└─ dto/
application/
└─ service/
└─ command/
└─ query/
domain/
└─ entity/
└─ vo/
└─ service/
└─ repository/
└─ event/
└─ aggregate/
infrastructure/
└─ repository/
└─ external/
└─ config/
DDD vs MVC 구조 비교
구조 차이 개요 표 |구분|MVC|DDD| |---|----|---| |목적|빠른 개발, 화면 중심|도메인 복잡도 관리, 비즈니스 중심| |주요 관심사|UI 흐름 제어|도메인 모델링, 규칙 중심| |계층 구성|Model, View, Controller|Presentation, Application, Domain, Infrastructure| |Model 역할|DB 매핑 + 비즈니스 로직 혼재|Domain Entity/VO/Service로 역할 분리| |서비스 레이어|필수 아님|Application Service + Domain Service로 명확 분리| |DTO 필요성|경우에 따라 생략 가능|필수적 (계층 간 책임 분리)| |일관성|상대적으로 느슨함|Aggregate 중심 강한 일관성|
DDD의 장점과 단점
장점
-
복잡한 도메인 표현에 강함
- 비즈니스 규칙이 코드 구조에 반영됨
- 유지보수 시 규칙 이해가 쉬움
-
변경에 강한 구조
- UI, DB 기술이 바뀌어도 Domain은 영향받지 않음
- 확장성 ↑
-
팀 간 협업 향상
- 도메인 언어(Ubiquitous Language)를 통해 동일 용어 사용 가능
-
테스트 용이
- Domain이 순수 로직만 담고 있기 때문에 단위 테스트 쉬움
단점
-
설계 비용이 높음
- 모델링 회의, Aggregate 설계, 이벤트 설계 등
- 소규모 프로젝트에는 과할 수 있음
-
학습 난이도
- DDD 개념(VO, Aggregate, Event 등)을 모두 이해해야 효과적
-
계층 분리로 초기 개발 속도 저하
- 파일/클래스 갯수 증가
- 단순 CRUD에서는 비효율적일 수 있음
MVC 대비 DDD를 선택해야 할 시점
DDD가 적합한 경우
- 도메인 규칙이 복잡하거나 자주 바뀜
- 금융, 결제, 유통, 정책 기반 시스템
- 장기 운영을 전제로 한 서비스
MVC 또는 단순 구조가 적합한 경우
- 단순 CRUD 위주의 시스템
- MVP 단계, 빠른 출시가 최우선
- 도메인 규칙이 거의 없음