|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "도메인 주도 설계의 사실과 오해" |
| 4 | +description: "Domain-Driven Design Fact and Misunderstanding" |
| 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 | + 특히, 마이크로서비스 아키텍처(MSA) 가 확산이 되면서, DDD 의 개념이 적극적으로 활용되고 있다. <br> |
| 17 | + 그렇다면, 도메인 주도 설계는 무엇이며, 도메인 주도 설계의 사실과 오해에 대해서 알아보자. |
| 18 | + <p style='margin-top:1em;'/> |
| 19 | + |
| 20 | +</div> |
| 21 | + |
| 22 | + |
| 23 | +## Intro |
| 24 | + |
| 25 | +--- |
| 26 | + |
| 27 | +들어가기에 앞서서, 도메인 주도 설계가 처음 이야기 되었을 때와 현재의 도메인 주도 설계는 조금은 다르다고 할 수 있다. |
| 28 | +하지만, 초창기의 도메인 주도 설계의 철학과 핵심 원칙에서는 크게 벗어나지는 않는다. |
| 29 | +개인적으로는 에릭 에반스가 작성한, ["도메인 주도 설계 - 소프트웨어의 복잡성을 다루는 지혜"](https://www.yes24.com/Product/Goods/5312881) 라는 책은 개발자라면, 읽어보기를 권장하고 싶고, |
| 30 | +[Nextstep 에서 진행하는 조영호님의 강의인 "도메인 주도 설계의 사실과 오해"](https://edu.nextstep.camp/c/SXgXIKdd/)도 추천한다. |
| 31 | + |
| 32 | +<br> |
| 33 | + |
| 34 | +## DDD 란 무엇인가? |
| 35 | + |
| 36 | +--- |
| 37 | + |
| 38 | +**도메인 주도 설계(Domain-Driven Design, DDD)** 는 복잡한 비즈니스 도메인을 효과적으로 다루기 위해 **도메인 중심의 사고방식과 설계 원칙을 적용하는 철학적인 관점** 에 가깝다. |
| 39 | +특정한 방법론이나 아키텍처가 아니라, 순수하게 **비즈니스 중심으로 사고하는 방식** 이다. |
| 40 | + |
| 41 | + |
| 42 | +<br> |
| 43 | + |
| 44 | +## DDD 의 철학과 핵심 원칙 |
| 45 | + |
| 46 | +--- |
| 47 | + |
| 48 | +### DDD 의 핵심 철학 |
| 49 | + |
| 50 | +DDD 의 핵심 철학은 |
| 51 | +<span style="color:blue"> |
| 52 | +<b> 복잡한 소프트웨어를 효과적으로 관리하고, 비즈니스 문제를 올바르게 모델링하여 해결 하는 것</b> |
| 53 | +</span> |
| 54 | +이다. |
| 55 | +단순히 코드 작성하는 것이 아닌, **도메인 전문가와 개발자가 협력하여 도메인을 깊이 이해하고, 이를 소프트웨어에 반영하는 방식** 을 추구한다. |
| 56 | +DDD 는 화려한 기술이나, 기법, 마법이 아니라 |
| 57 | +<span style="color:blue"> |
| 58 | +<b> 복잡한 소프트웨어를 효과적으로 관리하는 철학과 전략 </b> |
| 59 | +</span> |
| 60 | +이라고 할 수 있다. |
| 61 | + |
| 62 | +<div id="notice--note"> |
| 63 | + |
| 64 | + <p style='margin-top:1em;'> |
| 65 | + <b> 📘 Note - DDD 는 복잡성을 관리하고 문제를 협력적으로 해결하기 위한 것이다.</b> |
| 66 | + </p> |
| 67 | + 📌 복잡성 관리 - 복잡한 비즈니스 도메인을 효과적으로 다루기 위한 접근 방식 <br> |
| 68 | + ✏️ 복잡한 소프트웨어를 관리 가능한 형태로 모델링한다. <br> |
| 69 | + ✏️ 불필요한 복잡성을 제거하고, 필요한 복잡성을 효과적으로 관리한다. <br> |
| 70 | + 📌 협력적 문제 해결 - 도메인 전문가와 개발자 간의 지속적인 협력 <br> |
| 71 | + ✏️ 공통된 언어(유비쿼터스 언어) 를 통한 효과적인 의사소통이 필요하다. <br> |
| 72 | + ✏️ 비즈니스 문제에 대한 공동의 이해를 바탕으로 해결 방안을 도출한다. |
| 73 | + <p style='margin-top:1em;' /> |
| 74 | + |
| 75 | +</div> |
| 76 | + |
| 77 | + |
| 78 | +<br> |
| 79 | + |
| 80 | +### DDD 의 철학을 이루는 핵심 원칙 |
| 81 | + |
| 82 | +--- |
| 83 | + |
| 84 | +<b> 📌 도메인과 모델 우선 (핵심 철학) </b> |
| 85 | + |
| 86 | +> 소프트웨어의 본질은 도메인의 개념과 로직을 표현하는 것이다. <br> |
| 87 | +> "소프트웨어는 현실 세계의 복잡성을 해결하기 위한 것이므로, 도메인을 깊게 이해하고 모델을 만들어야 한다." |
| 88 | +
|
| 89 | +* 기술적 해결책 보다 **비즈니스 도메인 문제 해결** 을 우선시 한다. |
| 90 | +* 도메인 전문가와 협력하여 **비즈니스 개념을 정확히 반영** 해야 한다. |
| 91 | +* 도메인을 단순화 하고, 핵심 개념을 명확히 모델링 해야한다. |
| 92 | + |
| 93 | +<br> |
| 94 | + |
| 95 | +<b> 📌 유비쿼터스 언어 (Ubiquitous Language) </b> |
| 96 | + |
| 97 | +> 모든 이해관계자가 같은 언어를 사용해야 한다. <br> |
| 98 | +> "도메인 전문가와 개발자가 같은 용어를 사용해야 오해를 줄이고 효과적으로 협업할 수 있다." |
| 99 | +
|
| 100 | +* 도메인 전문가와 개발자가 동일한 언어를 사용하여 커뮤니케이션해야 혼선이 일어나지 않는다. |
| 101 | +* 이 언어는 **코드, 문서, 대화**에서 일관되게 유지되어야 한다. |
| 102 | +* 모델과 코드가 유비쿼터스 언어를 반영해야 한다. |
| 103 | + |
| 104 | +<br> |
| 105 | + |
| 106 | +<b> 📌 바운디드 컨텍스트 (Bounded Context) </b> |
| 107 | + |
| 108 | +> 모델의 적용 범위를 명확히 정의 해야한다. <br> |
| 109 | +> "하나의 모델이 모든 곳에 통하지 않는다. 바운디드 컨텍스트를 설정한다." |
| 110 | +
|
| 111 | +* 하나의 도메인을 여러개의 경계(Context) 로 나눈다. |
| 112 | +* 각 컨텍스트 내에서 유비쿼터스 언어를 일관되게 적용한다. |
| 113 | +* 컨텍스트 간 관계를 명확히 정의하고, 통합 전략을 고민해야 한다. |
| 114 | + |
| 115 | +<br> |
| 116 | + |
| 117 | +<b> 📌 어그리게이트 (Aggregate) </b> |
| 118 | + |
| 119 | +> 모델을 더 작은 단위로 구조화해야 한다. <br> |
| 120 | +> "무질서한 객체들 대신, 일관성과 응집력을 가진 어그리게이트를 만들자." |
| 121 | +
|
| 122 | +* 어그리게이트는 도메인 객체의 논리적 그룹이며, 일관성을 유지하는 단위이다. |
| 123 | +* Root Entity 가 변경을 관리하고, 외부에서 직접 내부 객체를 조작할 수 없다. |
| 124 | +* 트랜잭션 범위를 고려하여 적절한 크기로 모델링 해야 한다. |
| 125 | + |
| 126 | +<br> |
| 127 | + |
| 128 | +<b> 📌 도메인 이벤트 (Domain Event) </b> |
| 129 | + |
| 130 | +> 비즈니스 흐름을 명확하게 표현해야 한다. <br> |
| 131 | +> "중요한 상태 변화는 이벤트로 명확하게 드러내자." |
| 132 | +
|
| 133 | +* 도메인 내에서 중요한 상태 변화를 이벤트로 표현한다. |
| 134 | +* 이벤트 기반 설계를 활용하여 시스템 간 결합도를 낮춘다. |
| 135 | +* 이벤트는 과거 시제로 표현하며, 도메인 로직의 핵심 흐름을 반영해야 한다. |
| 136 | + |
| 137 | +<br> |
| 138 | + |
| 139 | +<b> 📌 리포지토리 (Repository) </b> |
| 140 | + |
| 141 | +> 도메인 객체의 저장과 검색을 추상화해야 한다. <br> |
| 142 | +> "데이터베이스가 아니라, 도메인 개념을 중심으로 접근하자." |
| 143 | +
|
| 144 | +* 리포지토리는 어그리게이트를 저장하고 검색하는 역할을 한다. |
| 145 | +* 도메인 로직에서 직접 데이터베이스 기술을 다루지 않는다. |
| 146 | +* 트랜잭션을 고려하여 적절한 데이터 접근 전략을 수립한다. |
| 147 | + |
| 148 | +<br> |
| 149 | + |
| 150 | +<b> 📌 어플리케이션 서비스 vs 도메인 서비스 </b> |
| 151 | + |
| 152 | +> 도메인 로직과 어플리케이션 로직을 명확히 분리해야 한다. <br> |
| 153 | +> "비즈니스 로직과 어플리케이션 로직을 혼합하지 말자." |
| 154 | +
|
| 155 | +* 도메인 서비스 : 어그리게이트에 속하지 않는 도메인 로직을 처리한다. |
| 156 | +* 어플리케이션 서비스 : 트랜잭션, 외부 API 호출 등 어플리케이션 수준의 처리를 담당한다. |
| 157 | +* 도메인 로직은 도메인 모델 내에서 처리하고, 어플리케이션 로직은 별도로 관리해야 한다. |
| 158 | + |
| 159 | +<br> |
| 160 | + |
| 161 | +<b> 📌 전략적 설계 (Strategic Design) </b> |
| 162 | + |
| 163 | +> 시스템 전체적인 설계를 고려해야 한다. <br> |
| 164 | +> "DDD 는 단순한 전술적 패턴이 아니라, 전략적 사고를 요구한다." |
| 165 | +
|
| 166 | +* 핵심 도메인(Core Domain) 을 식별하고, 여기에 집중해야 한다. |
| 167 | +* 지원 서브도메인(Supporting Subdomain) 과 범용 서브도메인(Generic Subdomain)을 구분해야 한다. |
| 168 | +* 도메인의 전략적 우선순위를 정하고, 각 컨텍스트 간 협력 관계를 정의해야 한다. |
| 169 | + |
| 170 | +<br> |
| 171 | + |
| 172 | +### DDD 핵심 원칙의 순서적 흐름 |
| 173 | + |
| 174 | +도메인 이해 → 유비쿼터스 언어 정립 → 바운디드 컨텍스트 설정 → 모델 구조화(어그리게이트, 이벤트, 리포지토리) → 전략적 설계 적용 |
| 175 | + |
| 176 | +DDD 의 철학은 **소프트웨어가 도메인을 정확하게 반영해야 한다는 원칙** 을 중심으로 **전술적 패턴**과 **전략적 설계** 로 체계화하는 것이다. |
| 177 | + |
| 178 | + |
| 179 | +<div id="notice--note"> |
| 180 | + |
| 181 | + <b> 📢 즉, DDD 는 "코딩 방식" 이 아니라, "비즈니스 문제를 해결하는 사고 방식" 이다. </b> |
| 182 | + |
| 183 | +</div> |
| 184 | + |
| 185 | +<br> |
| 186 | + |
| 187 | + |
| 188 | +## DDD 에 대한 사실과 오해 |
| 189 | + |
| 190 | +--- |
| 191 | + |
| 192 | +### ✅ DDD 에 대한 사실 |
| 193 | + |
| 194 | +|질문| 사실 ✅ | |
| 195 | +|--|-----------------------------------------------------------------------| |
| 196 | +|특정한 아키텍처(ex: 헥사고날, MSA)를 강제하나요? | 특정한 아키텍처를 강제하지 않지만, 다양한 아키텍처에서 적용 가능하다. | |
| 197 | +|도메인 모델을 처음부터 완벽하게 설계 해야하나요? | DDD 는 **반복적인 개발과 피드백을 통한 도메인 모델을 개선** 하는 방식이다. | |
| 198 | +|도메인 모델이 하나여야 하나요? | 하나의 시스템에서 **여러개의 도메인 모델이 존재 할 수 있다.(바운디드 컨텍스트)** | |
| 199 | +|기술적인 요소보다 비즈니스 로직이 우선되어야 하나요? | DDD 의 핵심은 **비즈니스 로직을 먼저 고려 하는 것**이다. | |
| 200 | +|복잡한 도메인을 다룰 때 효과적인가요? | 비즈니스 로직이 복잡한 경우 DDD 를 적용하면 효과적이다. | |
| 201 | +|도메인 전문가와의 협업은 필수 인가요? | 개발자와 도메인 전문과는 밀접한 관계를 가져야하고, <br> 도메인 전문가와의 협업은 DDD 의 **핵심요소** 중 하나다. | |
| 202 | + |
| 203 | +<br> |
| 204 | + |
| 205 | +### ❌ DDD 에 대한 오해 - MSA, 헥사고날, CQRS.. |
| 206 | + |
| 207 | +| 질문 | 오해 ❌ | |
| 208 | +|------------------------------|----------------------------------------------------------------------------------------------------------------------------| |
| 209 | +| 반드시 MSA 나 헥사고날 아키텍쳐를 해야 하나요? | 무조건 MSA 를 해야 한다는 것은 오해이고, <br> MSA 가 각광을 받으면서 설명하기 쉬우니 DDD 로 예를 드는 것이다. <br> 도메인 레이어만 분리가 잘되어 있다면 헥사고날이든 MSA 든 필요가 없다. | |
| 210 | +|처음부터 모든 모델을 이벤트 스토밍으로 정의 해야 하나요? | 한 번에 모든 모델을 정의하는 것은 아니다. | |
| 211 | +|CQRS 는 원래 DDD 의 일부였나요? | CQRS 는 시스템 복잡성을 낮추기 위해서 나온 것이고, <br> DDD 는 복잡도가 높으면 나누자였는데, <br> 현대의 DDD 에서는 CQRS 가 포함되는데, CQRS 가 DDD 의 복잡성을 해결하기 때문이다. | |
| 212 | +|모든 프로젝트에서 반드시 필요한가? | **비즈니스 로직이 복잡한 프로젝트에는 적합** <br> 하지만, 단순한 CURD 시스템에서는 오히려 부담이 될 수 있다. | |
| 213 | + |
| 214 | + |
| 215 | +<br> |
| 216 | + |
| 217 | +### ❌ DDD 에 대한 오해 - OOP |
| 218 | + |
| 219 | +|구분|객체지향(OOP)|도메인 주도 설계(DDD)| |
| 220 | +|--|--|--| |
| 221 | +|목적|작은 문제 해결, 유지보수 용이한 코드 배치|도메인 중심의 사고방식 적용| |
| 222 | +|초점|**데이터** 와 **알고리즘** 을 객체 단위로 배치|**비즈니스 도메인 로직**을 중심으로 코드 구성| |
| 223 | +|본질|**기술적인 개념**이 중심|**도메인의 본질을 코드로 표현하는 것**이 중심| |
| 224 | +|모델링 범위|클래스, 인터페이스 등 기술적인 모델링|바운디드 컨텍스트를 기반으로 도메인 모델링| |
| 225 | +|변경 관리|리팩토링을 통해 설계 개선|도메인 전문가와 협업하여 지속적 리팩토링| |
| 226 | + |
| 227 | + |
| 228 | +<div id="notice--note"> |
| 229 | + |
| 230 | + <b> 📢 즉, 객체지향은 기술적인 접근 방식이고, DDD 는 비즈니스 도메인을 중심으로 소프트웨어를 개발하는 방식이다. </b> |
| 231 | + |
| 232 | +</div> |
| 233 | + |
| 234 | + |
| 235 | +<br> |
| 236 | + |
| 237 | +## 현대의 DDD |
| 238 | + |
| 239 | +--- |
| 240 | + |
| 241 | +<b> 📌 CQRS 와 이벤트 소싱의 도입 </b> |
| 242 | + |
| 243 | +* 현래 DDD 의 일부는 아니었지만, 최근에는 복잡성을 해결하기 위해서 활용되고 포함해서 이야기 된다. |
| 244 | +* CQRS 는 읽기/쓰기 모델을 분리하여 성능을 개선할 수 있다. |
| 245 | +* 이벤트 소싱을 통해 상태 변경 이력을 추적 가능하게 한다. |
| 246 | + |
| 247 | +<b> 📌 MSA 와 DDD 의 관계 </b> |
| 248 | + |
| 249 | +* 바운디드 컨텍스트를 기반으로 MSA 를 설계 할 수 있다. |
| 250 | +* **그러나 DDD 를 한다고 반드시 MSA 를 도입할 필요는 없다.** |
| 251 | + |
| 252 | +<b> 📌 전략적 설계와 전술적 설계의 발전 </b> |
| 253 | + |
| 254 | +* 현대의 DDD 에서는 구체적인 전술 패턴(CQRS, 이벤트 소싱)과 전략 패턴(바운디드 컨텍스트, 컨텍스트 맵 등)이 발전 |
| 255 | + |
| 256 | +<b> 📌 점진적 도입 강조 </b> |
| 257 | + |
| 258 | +* 핵심 도메인부터 적용하고, 점신적으로 확장하는 방식이 현실적이다. |
| 259 | +* 처음부터 완벽한 설계를 하려 하기 보다 반복적인 리팩토링과 피드백을 통해 발전 |
| 260 | + |
| 261 | + |
| 262 | +## CQRS (Command Query Responsibility Segregation) 란? |
| 263 | + |
| 264 | +--- |
| 265 | + |
| 266 | +**CQRS는 "명령(Command)와 조회(Query) 의 책임을 분리하는 아키텍처 패턴"** 이다. |
| 267 | +즉, 읽기(조회)와 쓰기(명령)을 별도의 모델로 나누어 설계하는 방식이다. |
| 268 | + |
| 269 | +<b> 📌 CQRS 의 핵심 개념 </b> |
| 270 | + |
| 271 | +* Command (명령) |
| 272 | + * 생성, 수정, 삭제와 같이 데이터를 변경하는 작업 |
| 273 | + * 데이터 일관성과 트랜잭션을 유지하는 것이 중요 |
| 274 | +* Query (조회) |
| 275 | + * 검색, 조회와 같이 데이터를 읽는 작업 |
| 276 | + * 성능 최적활르 위해 별도의 읽기 모델을 구성할 수 있다. |
| 277 | + |
| 278 | + |
| 279 | +<b> 📌 CQRS 를 왜 사용할까? </b> |
| 280 | + |
| 281 | +✅ 읽기/쓰기 성능 최적화가 가능하여 조회가 많은 시스템에서 빠른 성능을 제공할 수 있다. |
| 282 | +✅ 읽기와 쓰기를 각각 독립적으로 확장 가능하여 확장성이 향상된다. |
| 283 | +✅ 복잡한 도메인 로직을 분리하여 유지보수성이 개선된다. |
| 284 | + |
| 285 | +But,, |
| 286 | +⚠️ 구현이 복잡해지고 유지보수가 어려워 질 수 가 있다. |
| 287 | +⚠️ 데이터 동기화가 필요할 수 있다. |
| 288 | + |
| 289 | + |
| 290 | +<br><br> |
| 291 | + |
| 292 | +<div id="notice--success"> |
| 293 | + |
| 294 | + <p style='margin-top:1em;'> |
| 295 | + <b> 📗 요약 </b> |
| 296 | + </p> |
| 297 | + 🖐 DDD 의 핵심 철학은 비즈니스 도메인을 깊게 이해하고 소프트웨어에 정확히 반영하는 것이다. <br> |
| 298 | + 🖐 DDD 는 모든 프로젝트에 적용해야만 하는 것은 아니고, 비즈니스 복잡성에 따라 적절히 활용하는 것이다. <br> |
| 299 | + 🖐 핵심 도메인에 집중하고, 변화에 유연하게 대응할 수 있도록 설계하는 것이 철학이라고 볼 수 있다. <br> |
| 300 | + 🖐 DDD 를 적용한다면 모든 문제를 해결할 수 있다는 것은 잘못됐다. 왜냐면 DDD 는 철학과 사상에 가깝기 때문이다. <br> |
| 301 | + 🖐 도메인 전문가와 개발자가 끊임 없이 협력 유비쿼터스 언어로 소통하고 발전해나가는 것이 중요하다. <br> |
| 302 | + |
| 303 | + <p style='margin-top:1em;' /> |
| 304 | + |
| 305 | +</div> |
| 306 | + |
| 307 | +<br><br> |
| 308 | + |
| 309 | +## Reference |
| 310 | + |
| 311 | +--- |
| 312 | + |
| 313 | +* ["도메인 주도 설계 - 소프트웨어의 복잡성을 다루는 지혜"](https://www.yes24.com/Product/Goods/5312881) |
| 314 | +* [Nextstep 에서 진행하는 조영호님의 강의인 "도메인 주도 설계의 사실과 오해"](https://edu.nextstep.camp/c/SXgXIKdd/) |
| 315 | + |
| 316 | +<br> |
0 commit comments