티스토리 뷰
목차
MSA 아키텍처 설계를 고민하다 보면 반드시 마주치는 개념이 있다.
바로 DDD, Domain-Driven Design (도메인 주도 설계)이다.
DDD는 단순한 설계 기법이 아니다.
비즈니스와 개발이 완전히 같은 언어를 공유하면서 시스템을 설계하는 철학이다.
이번 포스팅에서는 DDD가 무엇인지, 왜 필요한지, 실제로 도메인을 어떻게 모델링하고 서비스로 분리할 수 있는지까지 A to Z로 전부 정리해보겠다.
1️⃣ DDD란 무엇인가?
DDD(Domain-Driven Design)는 복잡한 비즈니스 로직을 효과적으로 다루기 위한 설계 방법론이다.
📌 키워드만 간단히 정리하면
- Domain (도메인) : 비즈니스 영역 (ex. 주문, 결제, 정산 등)
- Model (모델) : 도메인을 코드로 옮긴 표현
- Ubiquitous Language (통합 언어) : 개발자와 비즈니스가 동일한 용어로 대화
- Bounded Context (경계 컨텍스트) : 도메인을 의미 단위로 나눈 경계
예시
"주문이 결제되면 배송을 준비한다"
-> 이 한 문장에서 "주문", "결제", "배송"이 각각 도메인이자 서비스 분리의 후보가 된다.
2️⃣ DDD가 왜 중요한가?
🧩 서비스 분리의 기준이 되기 때문
- MSA를 구현하려면 서비스를 나눌 기준이 필요하다.
- DDD는 이 기준을 비즈니스 중심으로 만들어준다.
- 기존의 기술 중심 분할 (컨트롤러/서비스/DAO)가 아니라
- 비즈니스 역할과 책임을 중심으로 코드를 분리할 수 있게 해준다.
3️⃣ DDD의 핵심 개념 정리
① Entity
- 고유한 식별자를 가진 객체 (예: 주문, 사용자)
- 상태가 시간이 지나도 유지됨
class Order {
private Long id;
private List<OrderItem> items;
}
② Value Object
- 식별자 없이 값 자체가 중요 (예: 주소, 전화번호)
- 불변 객체로 설계
class Address {
private String city;
private String street;
}
③ Aggregate
- Entity + 관련 Value Object의 집합
- 변경은 항상 루트(Aggregate Root)를 통해서만 가능
예: 주문(Order) 안에 여러 개의 주문 항목(OrderItem)이 있지만, 항상 Order 단위로 조작
④ Repository
- Aggregate를 조회/저장하는 인터페이스 (DB 접근)
interface OrderRepository {
Order findById(Long id);
void save(Order order);
}
⑤ Service
- 도메인 객체들이 할 수 없는 복잡한 비즈니스 로직을 담당
- 내부 로직은 최대한 도메인 객체에 위임하는 것이 좋다
⑥ Bounded Context
- 도메인의 의미가 유요한 의미적 경계
- 이 경계를 기준으로 서비스를 나누고 DB를 나눈다.
- 예시 : 결제라는 단어는 "주문 도메인"에서는 결제여부를 의미하고, "정산 도메인"에서는 정산금액을 의미할 수 있다. 이 경우 이 둘은 분명히 다른 Bounded Context다.
4️⃣ 도메인 모델링 어떻게 할까? (실무 방식)
✅ 1. 비즈니스 이해 먼저
- 기획자, PO, 현업과 협업하면서 용어와 흐름 정리
- 시나리오 기반으로 "주요 개체"와 "주요 흐름" 도출
✅ 2. 유비쿼터스 언어 정리
- 모든 팀원이 공통된 용어로 이야기하도록 용어집 작성
- '주문 등록', '배송 요청', '정산 승인' 등 이벤트 중심 용어 사용
✅ 3. 컨텍스트 맵(Context Map) 작성
- 각각의 도메인 경계를 시각화
- 도메인 간 관계 (Upstream/Downstream, ACL, Shared Kernel 등) 도식화
✅ 4. 도메인 -> 서비스로 나누기
- Bounded Context 기준으로 하나의 컨텍스트를 하나의 마이크로서비스로 전환
- 각 서비스는 자체 데이터, 자체 API만 사용
5️⃣ DDD 기반 설계 예시
예를 들어, 물류 시스템이라면 아래와 같은 도메인이 있을 수 있다.
| 도메인 | 주요 Entity | 주요 이벤트 |
| 주문 | Order, OrderItem | 주문 생성, 주문 변경 |
| 결제 | Payment | 결제 완료, 결제 실패 |
| 배송 | Delivery, Tracking | 배송 시작, 배송 완료 |
| 정산 | Settlement | 정산 승인, 정산 완료 |
- 이런 각각의 도메인이 곧 Bounded Context가 됨
- 각각 하나의 마이크로서비스로 분리 가능해짐
6️⃣ DDD 적용 시 주의할 점
- 너무 이론에 빠져 실무 적용 못하면 의미 없음
- 항상 복잡한 도메인에만 적용 (CRUD 중심 단순 시스템엔 과함)
- 유비쿼터스 언어는 실제 사용하는 말과 최대한 맞춰야 함
- 서비스 분리 후엔 통신/데이터 일관성 문제가 생기므로 Event-driven 구조 고려 필요
✅ 마무리
DDD는 단순히 설계 기법이 아니라, 비즈니스 언어와 개발 언어를 일치시키고, 도메인 경계를 중심으로 시스템을 설계하는 사고 방식이다.
실무에서는 무조건 이론대로 할 수는 없지만, 서비스를 비즈니스 중심으로 나누기 위한 기준으로 DDD만큼 강력한 도구는 아직 없다.