|
| 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 | + |
| 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 | + |
| 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 | + |
| 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 | + |
| 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 | + |
| 190 | + |
| 191 | +<br> |
| 192 | + |
| 193 | +### 설계 방법 |
| 194 | +* 설계 할 때 책임 주도 설계를 하고, (객체 지향 언어를 사용하니깐) 계약에 의한 설계를 따른다. |
| 195 | + |
| 196 | +### 기본 원칙 |
| 197 | +* 책임 주도 설계 → 객체 지향 / 계약에 의한 설계 → 불변식 |
| 198 | + |
| 199 | + |
| 200 | +## DDD 적용 사이클과 애자일과 비슷한 점 |
| 201 | + |
| 202 | +--- |
| 203 | + |
| 204 | + |
| 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 | + ✏️ DDD 는 도메인 쪽으로 찾으려고 하는 것이지, 기술적으로 접근하게 되면 사람들의 의견이 달라서 맞추기 힘들다. <br> |
| 237 | + 📌 일관성 <br> |
| 238 | + ✏️ 도메인이라는 기준으로 나누면 그대로 일관성 있게 갈 수 있다. <br> |
| 239 | + 📌 시스템 분할 <br> |
| 240 | + ✏️ 전체적으로 시스템을 나누거나 구현할 때 조금은 쉬울 수 있다. |
| 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 | + ➡️ 오버엔지니어링을 경계해야한다. 그래서 도메인 특성과 프로젝트의 필요에 맞추라는 것. <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> |
0 commit comments