Home DDD와 Hexagonal Architecture는 왜 같이 사용될까?
Post
Cancel

DDD와 Hexagonal Architecture는 왜 같이 사용될까?

0. 알아보게 된 이유

대부분의 자료에서 DDD를 설명할 때 함께 등장하는 구조가 있는데

  • Hexagonal Architecture
  • Clean Architecture
  • Layered Architecture

같은 아키텍처 스타일이 있다. 특히 ``Hexagonal ArchitectureDDD와 같이 설명되는 경우가 많았고, 도메인을 중심으로 설계한다는 점에서 DDD`와 매우 잘 맞는 구조라고 한다.

이번 글 에서는

  • Hexagonal Architecture란 무엇인가
  • DDD와 같이 사용되는가
  • 어떤 문제를 해결하기 위한 구조인가

를 중심으로 정리해 보려고 한다.

1. DDD만으로는 구조가 완성되지 않는다.

DDD자체는 도메인을 어떻게 설계할것인지 방법에 대한 제시를 할뿐 구조적인 문제를 어떻게 해결할 것인지에 대해서는 설명하지 않는다. 예를 들어

  • Entity를 어떻게 나눌지
  • Aggregate를 어떻게 묶을지
  • Domain Service를 언제 만들지

와 같은 기준을 제공하고

  • Controller를 어디에 둘지
  • Repository를 어디에 둘지
  • DB접근을 어떻게 할지
  • 외부API를 어떻게 연결할지

와 같은 구조적인 문제는 해결되지 않는다. 즉,

1
2
DDD = 모델링 기법
Architecture = 구조 설계 방법

이다.

그래서 DDD를 사용할 때는 도메인을 중심으로 구조를 잡을 수 있는 아키텍쳐가 필요하다. 그때 많이 사용하는 것이

1
Hexagonal Architecture

이다.

2. Hexagonal Architecture 란?

이전에 설명한 글이 있음으로 링크로 대체한다.

링크 : Hexagonal Architecture 란?

3. 왜 DDD와 잘 맞는가

DDD목표

1
도메인을 중심으로 설계

Hexagonal Architecture 목표

1
도메인을 외부로 부터 보호

위와 같이 둘다 Domain에 중점을 둔 설계와 구조이다.

4. 예시 구조

MSA + DDD + Hexagonal Architecture 기반으로 구성된 강의 프로젝트의 실제 구조를 참고하여 정리하였다.
해당 구조는 Domain / Application / Adapter / Container 를 명확하게 분리한 형태이며,
Ports & Adapters 패턴을 기준으로 의존성 방향이 Domain 내부를 향하도록 설계되어 있다.

아래는 Order 서비스의 모듈 구조 예시이다.

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
├─order-application
│  └─src
│      └─main
│          └─java
│              └─com
│                  └─food
│                      └─ordering
│                          └─system
│                              └─order
│                                  └─service
│                                      └─application
│                                          ├─exception
│                                          │  └─handler
│                                          └─rest
├─order-container
│  └─src
│      ├─main
│      │  ├─java
│      │  │  └─com
│      │  │      └─food
│      │  │          └─ordering
│      │  │              └─system
│      │  │                  └─order
│      │  │                      └─service
│      │  │                          └─domain
│      │  └─resources
│      └─test
│          ├─java
│          │  └─com
│          │      └─food
│          │          └─ordering
│          │              └─system
│          │                  └─order
│          │                      └─service
│          │                          └─domain
│          └─resources
│              └─sql
├─order-dataaccess
│  └─src
│      └─main
│          └─java
│              └─com
│                  └─food
│                      └─ordering
│                          └─system
│                              └─order
│                                  └─service
│                                      └─dataaccess
│                                          ├─customer
│                                          │  ├─adapter
│                                          │  ├─entity
│                                          │  ├─mapper
│                                          │  └─repository
│                                          ├─order
│                                          │  ├─adapter
│                                          │  ├─entity
│                                          │  ├─mapper
│                                          │  └─repository
│                                          ├─outbox
│                                          │  ├─payment
│                                          │  │  ├─adapter
│                                          │  │  ├─entity
│                                          │  │  ├─exception
│                                          │  │  ├─mapper
│                                          │  │  └─repository
│                                          │  └─restaurantapproval
│                                          │      ├─adapter
│                                          │      ├─entity
│                                          │      ├─exception
│                                          │      ├─mapper
│                                          │      └─repository
│                                          └─restaurant
│                                              ├─adapter
│                                              └─mapper
├─order-domain
│  ├─order-application-service
│  │  ├─src
│  │  │  ├─main
│  │  │  │  └─java
│  │  │  │      └─com
│  │  │  │          └─food
│  │  │  │              └─ordering
│  │  │  │                  └─system
│  │  │  │                      └─order
│  │  │  │                          └─service
│  │  │  │                              └─domain
│  │  │  │                                  ├─config
│  │  │  │                                  ├─dto
│  │  │  │                                  │  ├─create
│  │  │  │                                  │  ├─message
│  │  │  │                                  │  └─track
│  │  │  │                                  ├─mapper
│  │  │  │                                  ├─outbox
│  │  │  │                                  │  ├─model
│  │  │  │                                  │  │  ├─approval
│  │  │  │                                  │  │  └─payment
│  │  │  │                                  │  └─scheduler
│  │  │  │                                  │      ├─approval
│  │  │  │                                  │      └─payment
│  │  │  │                                  └─ports
│  │  │  │                                      ├─input
│  │  │  │                                      │  ├─message
│  │  │  │                                      │  │  └─listener
│  │  │  │                                      │  │      ├─customer
│  │  │  │                                      │  │      ├─payment
│  │  │  │                                      │  │      └─restaurantapproval
│  │  │  │                                      │  └─service
│  │  │  │                                      └─output
│  │  │  │                                          ├─message
│  │  │  │                                          │  └─publisher
│  │  │  │                                          │      ├─payment
│  │  │  │                                          │      └─restaurantapproval
│  │  │  │                                          └─repository

5. 정리

DDD는 도메인을 어떻게 설계할지 알려준다. Hexagonal Architecture는 도메인을 중심으로 구조를 만드는 방법을 알려준다.

DDD만 사용하면 구조가 흔들릴 수 있고 Hexagonal Architecture만 사용한다면 도메인이 약해질 수 있다. 그래서 실무에서는 둘을 같이 사용하는 경우가 많다.

결과적으로 좋은 설계의 기준은

1
도메인은 외부에 의존하지 않는다.

이다.

This post is licensed under CC BY 4.0 by the author.

DDD - Domain Service와 Application Service의 차이

AI Agent를 직접 만들어보려고 한 이유와 프로젝트 설정