Skip to content

Commit f299e1e

Browse files
committed
feat(post): 도메인 주도 설계의 핵심 개념
1 parent b144918 commit f299e1e

File tree

7 files changed

+294
-0
lines changed

7 files changed

+294
-0
lines changed
Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
---
2+
layout: post
3+
title: "도메인 주도 설계의 핵심 개념"
4+
description: "Domain-Driven Design Core Concept"
5+
excerpt: "도메인 주도 설계(DDD, Domain-Driven Design)의 핵심 개념을 정리해보자."
6+
category: Study
7+
comments: true
8+
---
9+
10+
<div id ="notice--info">
11+
12+
<p style='margin-top:1em;'>
13+
<b>🐱 Meow, meow </b>
14+
</p>
15+
도메인 주도 설계(DDD, Domain-Driven Desigin) 는 단순한 방법론이나 프로세스가 아닌, 도메인 중심의 개발 접근법이다. <br>
16+
그렇다면 핵심 개념에 대해서 알아보고, 정리해보자.
17+
<p style='margin-top:1em;'/>
18+
19+
</div>
20+
21+
## Intro
22+
23+
---
24+
25+
들어가기에 앞서서, 해당 내용은 [Nextstep 에서 진행하는 조영호님의 강의인 "도메인 주도 설계의 사실과 오해"](https://edu.nextstep.camp/c/SXgXIKdd/) 에서 배운 내용을 요약하고 정리한 부분이 포함되어 있다.
26+
해당 강의는 책으로 읽었던 내용들을 다시 정리할 수 있었던 부분들이 많았고, 개념정리를 다시 할 수 있어서 좋았는데, 개인적으로는 연차를 막론하고 적극 추천한다.
27+
28+
<br>
29+
30+
31+
## 도메인 주도 설계(DDD)의 본질
32+
33+
---
34+
35+
![ddd본질]({{site.baseurl}}/img/post/ddd/ddd.png)
36+
37+
<br>
38+
39+
### 접근법
40+
* DDD 는 프로게스나 방법론이 아니라 패턴의 집합이며, 자신의 상황에 맞는 것을 **선택적** 으로 적용 해야 한다.
41+
42+
### 모델링 사이틀
43+
* **도메인 모델 = 코드 모델**
44+
* 도메인이 바뀌면 코드가 바뀌고, 코드가 바뀌면 도메인 모델이 바뀌는 사이클을 가지고 있다.
45+
46+
### 구현 가이드
47+
* 빌딩 블록을 통해 도메인의 개념을 코드로 옮기고 **복잡도를 낮춘다.**
48+
49+
### 불변식 기반
50+
* DDD 는 불변식이라는 것이 깔려있는데, 기능 요구사항과 불변식을 어그리게이트 단위로 구현한다.
51+
52+
<br>
53+
54+
## 엔티티(Entity)와 값 객체(Value Object)
55+
56+
---
57+
58+
| 엔티티 (Entity) | 값 객체 (Value Object) |
59+
|---------------|---------------------|
60+
| 식별성이 중요 | 속성이 중요 |
61+
| 가변 (상태 변경 가능) | 불변 (변경 불가) |
62+
| 식별자로 동일성 비교 | 속성으로 동등성 비교 |
63+
| 생명 주기 추적 필요 | 대체 가능 / 엔티티의 복잡성 감소 |
64+
65+
<br>
66+
67+
### 엔티티 (Entity)
68+
* **식별성**이 중요하며, 상태 변경이 가능하다.
69+
* 생명 주기를 관리해야하며, **식별자****동일성**을 비교한다.
70+
* 트래킹이 필요하면 엔티티로 모델링한다.
71+
* 엔티티는 식별자로 불리기도 하는데, 가변 객체이며 상태를 변경하기 위해서 만드는 것이다.
72+
73+
74+
### 값 객체
75+
* **속성** 이 중요하며, **불변성** 이 유지되어야 한다.
76+
* 속성이 동일하면 같은 객체로 취급한다. (**동등성 비교**)
77+
* 엔티티의 복잡성을 줄이는 역할을 수행한다.
78+
* 같은 값이 A 클래스, B 클래스 에서 사용되면 값 객체로 추출하면 된다.
79+
80+
<div id="notice--note">
81+
82+
<b> 📢 상태 변경을 엔티티에 몰아주고 값을 모두 빼버리면 심플해지고, 선언적으로 코드가 짜여진다. </b>
83+
84+
</div>
85+
86+
<br>
87+
88+
## 어그리게이트 (Aggregate)
89+
90+
---
91+
92+
![aggregate]({{site.baseurl}}/img/post/ddd/aggregate.png)
93+
94+
<br>
95+
96+
### 정의
97+
* 여러 엔티티와 값 객체를 하나로 묶는 단위이다.
98+
99+
### 경계 설정
100+
* Aggregate 는 **캡슐화 경계를 형성** 하며, 외부에서는 **루트 엔티티만 참조 가능** 하다.
101+
102+
### 트랜잭션 단위
103+
* Aggregate 단위로 트랜잭션을 유지한다.
104+
105+
### 불변식
106+
* 트랜잭션과 일관성이 있는데, "불변식을 한번에 처리하겠어" 이게 Aggregate 이다.
107+
108+
<div id="notice--note">
109+
110+
<b> 📢 루트 엔티티는 전역 식별성을 가지고 있고, 궁극적으로 불변식을 검사할 책임이 있다. </b> <br>
111+
<b> 📢 경계 안의 엔티티는 지역 식별성을 지니고 있으며, 밖에선 무조건 루트 엔티티만 참조 가능하다. </b>
112+
113+
</div>
114+
115+
<br>
116+
117+
## 리포지토리 (Repository)
118+
119+
---
120+
121+
### 역할
122+
* Aggregate 단위(DDD 에서는 객체 단위가 아님)로 **영속성** 을 관리하며, 데이터 저장 및 검색을 담당한다.
123+
* DDD 에서는 원래의 Repository 는 컬렉션과 비슷한데, 메모리상에 객체가 있는 것처럼 쓰는 객체인데, 요즘에는 그냥 Database 라고 보면 된다.
124+
125+
### 설계 원칙
126+
* 객체 단위가 아닌 **Aggregate 단위** 로 리포지토리 생성한다. (Aggregate 당 하나의 Repository)
127+
* ID 를 통해 외부에서 참조하며, 내부에서는 객체를 참조한다.
128+
129+
<br>
130+
131+
## 연관 관계 설계 원칙
132+
133+
---
134+
135+
![설계원칙]({{site.baseurl}}/img/post/ddd/design-principles.png)
136+
137+
<br>
138+
139+
**✅ 단방향 선호**
140+
**✅ N:1 관계 선호**
141+
**✅ 불필요한 연관관계 제거**
142+
143+
**❌ 양방향 지양**
144+
**❌ 1:N 관계 지양**
145+
146+
### 접근 방법
147+
* 도메인은 무조건 **행위** 인 것이다. 행위 관점에서 연관관계가 있는지를 확인해야한다.
148+
149+
### 단방향 참조 선호
150+
* 양방향 참조는 복잡성을 증가시키므로 가급적 단방향으로 설계한다.
151+
152+
### N:1 관계 선호
153+
* 1:N 관계는 지연 로딩 문제로 인해 선호하지 않는다.
154+
155+
### 불필요한 연관관계 제거
156+
* ID 참조를 통해 외부 참조를 최소화하고, Aggregate 내부에서는 객체 참조를 통해 탐색한다.
157+
158+
159+
<br>
160+
161+
## 서비스 계층 구조
162+
163+
---
164+
165+
![서비스계층구조]({{site.baseurl}}/img/post/ddd/service-hierarchy.png)
166+
167+
<br>
168+
169+
### 분류
170+
* DDD 에서는 서비스를 인프라 서비스, 애플리케이션 서비스, 도메인 서비스로 나눈다.
171+
172+
### 애플리케이션 서비스
173+
* 일반적으로 우리가 알고 있는 서비스를 의미한다.
174+
175+
### 도메인 서비스
176+
* 도메인 로직에서 서비스는 도메인 로직을 Aggregate 로 넘기기 애매하면 서비스로 만들라는 것이다.
177+
178+
### 인프라 서비스
179+
* Database 접근, 외부 시스템 통합, 도메인 및 애플리케이션 계층이 기술적 세부 사항에 의존하지 않도록 추상화 계층을 제공한다.
180+
* 로깅, 모니터링, 캐싱, 메시지 큐 관리 등 같은 시스템 기반 서비스를 제공한다.
181+
182+
183+
<br>
184+
185+
## 설계 접근법
186+
187+
---
188+
189+
![설계접근법]({{site.baseurl}}/img/post/ddd/design-principles.png)
190+
191+
<br>
192+
193+
### 설계 방법
194+
* 설계 할 때 책임 주도 설계를 하고, (객체 지향 언어를 사용하니깐) 계약에 의한 설계를 따른다.
195+
196+
### 기본 원칙
197+
* 책임 주도 설계 → 객체 지향 / 계약에 의한 설계 → 불변식
198+
199+
200+
## DDD 적용 사이클과 애자일과 비슷한 점
201+
202+
---
203+
204+
![DDD 적용 사이클]({{site.baseurl}}/img/post/ddd/ddd-cycle.png)
205+
206+
<br>
207+
208+
DDD 의 적용 흐름 사이클은 애자일 방법론과 매우 밀접하게 연관이 있다.
209+
두 접근법 모두 반복적이고 점진적인 개선을 중요시 한다는 특성이 있다.
210+
211+
<br>
212+
213+
#### 📌 반복적 개발
214+
* 한 번에 완벽한 시스템을 구축하기 보다는 **반복적인 사이클** 을 통해 **점진적** 으로 시스템을 발전 시키는 접근법이다.
215+
216+
#### 📌 지속적인 피드백
217+
* 애자일에서 중요시하는 지속적인 피드백 루프가 DDD 의 테스트 - 리팩토팅 - 도메인 분석 순환과 유사하다.
218+
219+
#### 📌 협업 중심
220+
* 애자일은 개발자와 이해관계자 간의 긴밀한 협업을 강조하고, DDD 는 도메인 전문가와 개발자 간의 지식 공유와 협업이 핵심이다.
221+
222+
#### 📌 변화 수용
223+
* 애자일과 DDD 모두 요구사항과 이해의 변화를 자연스럽게 수용하는 프레임워크를 제공한다고 볼 수 있다.
224+
225+
#### 📌 점진적 모델 개선
226+
* 애자일의 점진적 개발 방식은 DDD 에서 도메인 모델을 점진적으로 발견하고 개선해 나가는 과정과 동일하다고 볼 수 있다.
227+
228+
229+
230+
<div id="notice--note">
231+
232+
<p style='margin-top:1em;'>
233+
<b> 📘 DDD 의 가치 </b>
234+
</p>
235+
📌 도메인 중심 접근 <br>
236+
&nbsp;&nbsp; ✏️ DDD 는 도메인 쪽으로 찾으려고 하는 것이지, 기술적으로 접근하게 되면 사람들의 의견이 달라서 맞추기 힘들다. <br>
237+
📌 일관성 <br>
238+
&nbsp;&nbsp; ✏️ 도메인이라는 기준으로 나누면 그대로 일관성 있게 갈 수 있다. <br>
239+
📌 시스템 분할 <br>
240+
&nbsp;&nbsp; ✏️ 전체적으로 시스템을 나누거나 구현할 때 조금은 쉬울 수 있다.
241+
242+
<p style='margin-top:1em;' />
243+
244+
</div>
245+
246+
<br>
247+
248+
## 실용적 적용 Tips
249+
250+
---
251+
252+
#### 📌 결정의 유연성
253+
* 도메인에서 이게 엔티티고, 값 객체이다 이런 정형적인 답은 없다. 상황에 따라서 정하는 것이다.
254+
255+
#### 📌 점진적 접근
256+
* 어떤걸 엔티티로, 어떤걸 값 객체로 해야할지 잘 모르겠다면, 값 객체로 모델링하고 엔티티로 올리면 된다.
257+
258+
#### 📌 값 객체 추출
259+
* 처음부터 값 객체를 뜯어내서 개발하는 경우는 잘 없다.
260+
* 리팩토링을 할 때 같은 값이 A 클래스, B 클래스에서 사용된다면 값 객체로 신분을 상승시키면 된다.
261+
262+
#### 📌 Aggregate 설계
263+
* Aggregate 설계는 기능 구현과 불변식을 고려해서 설계한다.
264+
265+
266+
<br><br>
267+
268+
<div id="notice--success">
269+
270+
<p style='margin-top:1em;'>
271+
<b> 📗 요약 </b>
272+
</p>
273+
🖐 DDD 는 단순한 방법론이 아닌 복잡한 도메인을 코드로 명확하게 표현하기 위한 사고방식이다. <br>
274+
🖐 DDD 의 핵심은 도메인 모델을 코드로 일관되게 유지하고 복잡성을 줄이고 불변식을 관리하는 것이다. <br>
275+
🖐 적용할 때는 패턴을 강박적으로 따르는 것보다는 도메인의 특성과 프로젝트의 필요에 맞춰서 유연하게 차용해서 사용하면 된다. <br>
276+
&nbsp;&nbsp; ➡️ 오버엔지니어링을 경계해야한다. 그래서 도메인 특성과 프로젝트의 필요에 맞추라는 것. <br>
277+
🖐 애자일과 유사하게 점진적으로 모델을 개선하는 방식으로 접근하는 것이 현실적인 DDD 적용의 핵심이다. <br>
278+
279+
<p style='margin-top:1em;' />
280+
281+
</div>
282+
283+
<br><br>
284+
285+
286+
287+
## Reference
288+
289+
---
290+
291+
* ["도메인 주도 설계 - 소프트웨어의 복잡성을 다루는 지혜"](https://www.yes24.com/Product/Goods/5312881)
292+
* [Nextstep 에서 진행하는 조영호님의 강의인 "도메인 주도 설계의 사실과 오해"](https://edu.nextstep.camp/c/SXgXIKdd/)
293+
294+
<br>

img/post/ddd/aggregate.png

18.9 KB
Loading

img/post/ddd/ddd-cycle.png

19.5 KB
Loading

img/post/ddd/ddd.png

7.34 KB
Loading

img/post/ddd/design-approach.png

27 KB
Loading

img/post/ddd/design-principles.png

16 KB
Loading

img/post/ddd/service-hierarchy.png

19.2 KB
Loading

0 commit comments

Comments
 (0)