๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Backend/Spring

DDD(Domain Driven Design)๋ž€?

๐Ÿ“’ DDD(Domain Driven Design)

โœ” ๋„๋ฉ”์ธ์„ ์ค‘์‹ฌ์œผ๋กœ ๋‚˜๋ˆ„์–ด ์„ค๊ณ„ํ•˜๋Š” ๋””์ž์ธ ๋ฐฉ๋ฒ•๋ก ์ด๋‹ค. 

โ—ผ ๋„๋ฉ”์ธ์˜ ๋ชจ๋ธ๊ณผ ๋กœ์ง์— ์ง‘์ค‘ํ•œ๋‹ค.

โ—ผ ๋‹จ์ผํ™”๋œ, ๋ณดํŽธํ™”๋œ(ํ†ต์ผํ™”๋œ) ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

โ—ผ ๋ถ„์„ ๋ชจ๋ธ๊ณผ ์„ค๊ณ„, ๊ฐœ๋ฐœ ๋ชจ๋ธ์˜ ๊ฐœ๋…์ด ์ผ์น˜ํ•œ๋‹ค.

 

๐Ÿ’ฅ DDD์˜ ํƒ„์ƒ ๋ฐฐ๊ฒฝ

โ—ผ DDD๊ฐ€ ๋‚˜์˜ค๊ฒŒ ๋œ ์ด์œ ๋Š” ์„ค๊ณ„์ž์™€ ๊ฐœ๋ฐœ์ž ๋‘˜ ์‚ฌ์ด์˜ ์–ธ์–ด ์žฅ๋ฒฝ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•จ์œผ๋กœ, ์„ค๊ณ„์ž์™€ ๊ฐœ๋ฐœ์ž ๋ชจ๋‘ ๋„๋ฉ”์ธ ๊ด€์ ์—์„œ ๋ฌธ์ œ๋ฅผ ๋ฐ”๋ผ๋ณด๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด์„œ์ด๋‹ค.

โ—ผ ๋ณต์žกํ•œ ๋„๋ฉ”์ธ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  ์œ ์ง€๋ณด์ˆ˜ ๊ฐ€๋Šฅํ•œ ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ ๊ณ ์•ˆ๋˜์—ˆ๋‹ค.

 

๐Ÿ’ฅ Domain์ด๋ž€?

์‚ฌ์ „์ ์œผ๋กœ '์˜์—ญ', '์ง‘ํ•ฉ'์„ ์˜๋ฏธํ•˜๊ณ , ์‹ค์งˆ์ ์œผ๋กœ๋Š” ์šฐ๋ฆฌ๊ฐ€ ์†Œํ”„ํŠธ์›จ์–ด๋กœ ํ•ด๊ฒฐํ•˜๊ณ ์ž ํ•˜๋Š” ๋ฌธ์ œ์˜ ์˜์—ญ์„ ์˜๋ฏธํ•œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ์˜จ๋ผ์ธ ์Œ์‹ ์ฃผ๋ฌธ์ด๋ผ๋Š” ๋ฌธ์ œ๋ฅผ ์†Œํ”„ํŠธ์›จ์–ด๋กœ ํ•ด๊ฒฐํ•˜๊ณ ์ž ํ•œ๋‹ค๋ฉด, '์˜จ๋ผ์ธ ์Œ์‹ ์ฃผ๋ฌธ'์€ ๋„๋ฉ”์ธ์— ํ•ด๋‹น๋œ๋‹ค. ๋˜ํ•œ, ํ•œ ๋„๋ฉ”์ธ์€ ๋‹ค์‹œ ํ•˜์œ„ ๋„๋ฉ”์ธ์œผ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด ๊ฒฝ์šฐ์—์„œ๋Š” ๊ฒฐ์ œ, ๋ฐฐ์†ก, ์ •์‚ฐ, ์นดํƒˆ๋กœ๊ทธ ๋“ฑ์˜ ํ•˜์œ„ ๋„๋ฉ”์ธ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.

 

๐Ÿ’ฅ Domain Model

ํŠน์ • ๋„๋ฉ”์ธ์„ ๊ฐœ๋…์ ์œผ๋กœ ํ‘œํ˜„ํ•œ ๊ฒƒ์œผ๋กœ, ๊ธฐํš์ด๋‚˜ ๋””์ž์ธ, ๊ฐœ๋ฐœํ•  ๋•Œ ์˜์‚ฌ์†Œํ†ต์˜ ๋ชฉ์ ์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.

 

๐Ÿ“’ Domain Layer

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์„ค๊ณ„ํ•  ๋•Œ, ๋‹ค์Œ๊ณผ ๊ฐ™์ด 4๊ฐ€์ง€ ์˜์—ญ์œผ๋กœ ๋ถ„๋ฆฌ๋  ์ˆ˜ ์žˆ๋‹ค.

โ—ผ Presentation Layer: ํ‘œํ˜„์˜ ์˜์—ญ์œผ๋กœ, UI๋‚˜ ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ์„ ๋ฐ›์•„ Application ์˜์—ญ์œผ๋กœ ์ „๋‹ฌํ•˜๊ณ  ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋‹ค์‹œ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค. (Controller)

โ—ผ Application Layer: ์‘์šฉ์˜ ์˜์—ญ์œผ๋กœ, ์‹œ์Šคํ…œ์ด ์‚ฌ์šฉ์ž์—๊ฒŒ ์ œ๊ณตํ•  ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•œ๋‹ค. (Service)

โ—ผ Domain Layer: ๋„๋ฉ”์ธ์˜ ์˜์—ญ์œผ๋กœ ๋„๋ฉ”์ธ ๋ชจ๋ธ์„ ๊ตฌํ˜„ํ•œ๋‹ค. (์‚ฌ์šฉ์ž, ๊ฒŒ์‹œํŒ...)

โ—ผ Infrastructure Layer: ๊ตฌํ˜„ ๊ธฐ์ˆ ์˜ ์˜์—ญ์œผ๋กœ, ๊ตฌํ˜„ ๊ธฐ์ˆ ์— ๋Œ€ํ•œ ๊ฒƒ์„ ๋‹ค๋ฃฌ๋‹ค. (๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค, ์™ธ๋ถ€ API...)

 

โ— DDD์™€ ๊ด€๋ จ๋œ ์˜์—ญ์€ Domain Layer์ด๋ฉฐ, ๋„๋ฉ”์ธ ์˜์—ญ์€ ๋„๋ฉ”์ธ์„ ๊ตฌํ˜„ํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์‚ฌ์šฉ์ž ๋„๋ฉ”์ธ์ธ ๊ฒฝ์šฐ ์‚ฌ์šฉ์ž ๋น„๋ฐ€๋ฒˆํ˜ธ ๋ณ€๊ฒฝ, ์‚ฌ์šฉ์ž ์ •๋ณด ๋ณ€๊ฒฝ ๋“ฑ์˜ ๊ธฐ๋Šฅ๋“ค์„ Domain ๋‚ด์—์„œ ๊ตฌํ˜„ํ•œ๋‹ค.

 

๐Ÿ“’ DDD์˜ ์ค‘์š” ๊ฐœ๋…

โœ” Bounded Context 

์„œ๋น„์Šค๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ๊ตฌํ˜„ํ–ˆ์„ ๋•Œ, ๋ฌธ์ œ๊ฐ€ ์—†์ด ๋Œ์•„๊ฐ€๋Š” ์˜์—ญ, ์ฆ‰ ๋„๋ฉ”์ธ ๋ชจ๋ธ์ด ์ž‘๋™ํ•˜๋Š” ์ปจํ…์ŠคํŠธ๋ฅผ ๋ช…์‹œํ•˜๋Š” ๊ฒƒ

ํ•˜๋‚˜์˜ ํŒ๋งค ์‚ฌ์ดํŠธ๋ฅผ ๋งŒ๋“ค ๋•Œ, ๊ธฐ๋Šฅ ์˜์—ญ๋“ค์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

User, ์ปจํ…์ธ  ์ œ์ž‘, ์˜ˆ์•ฝ ๋ฐ ์•Œ๋ฆผ, ์ธ์ฆ, ๋ฉ”ํƒ€ ์ •๋ณด ๊ด€๋ฆฌ, ์ •์‚ฐ, 3rd Party, ํŒ๋งค, ํ†ต๊ณ„...

๋‹ค์–‘ํ•œ ์˜์—ญ๋“ค์„ ๊ฐ€์ง€๊ณ  ๋ถ„๋ฅ˜ํ•˜์—ฌ ์„œ๋กœ์˜ ์˜์กด์„ฑ์„ ์ค„์ด๊ธฐ ์œ„ํ•ด ๊ฒฝ๊ณ„๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ , ๊ฒฝ๊ณ„๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์„œ๋น„์Šค๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค. ์œ„ ์ƒํ™ฉ์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

User, ์ธ์ฆ, 3rd Party, ์ปจํ…์ธ  ์ œ์ž‘ + ๋ฉ”ํƒ€ ์ •๋ณด ๊ด€๋ฆฌ + ํŒ๋งค, ์˜ˆ์•ฝ ๋ฐ ์•Œ๋ฆผ, ์ •์‚ฐ + ํ†ต๊ณ„

โœ” Context Map

Bounded Context ๊ฐ„์˜ ๊ด€๊ณ„๋ฅผ ๋ณด์—ฌ์ค€๋‹ค.

โœ” Aggregate 

์—ฐ๊ด€๋œ Entity์™€ Value Object์˜ ๋ฌถ์Œ์œผ๋กœ, ๋ช…๋ น์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ํ•จ๊ป˜ ์กฐํšŒํ•˜๊ณ  ์—…๋ฐ์ดํŠธ ํ•ด์•ผ ํ•˜๋Š” ๋‹จ์œ„์ด๋‹ค.

์—ฐ๊ด€๋œ ๊ฐ์ฒด๋“ค์„ ๋ฌถ์–ด์„œ ํ•˜๋‚˜์˜ ๋‹จ์ผํ•œ ๊ฐœ๋…์œผ๋กœ ๋‹ค๋ฃจ๋Š” ํŒจํ„ด์ด๋‹ค.

 

โ— ๊ฐ™์€ Aggregate์— ์†ํ•˜๋Š” ์ƒํ™ฉ

์ฃผ๋ฌธ๊ณผ ์ฃผ๋ฌธ ์•„์ดํ…œ์€ ๋ชจ๋‘ ์ฃผ๋ฌธ ์‹œ์ ์— ์ƒ์„ฑ๋˜๊ณ  ์—…๋ฐ์ดํŠธ ๋˜๋ฏ€๋กœ ๊ฐ™์€ Aggregate์— ์†ํ•œ๋‹ค.

 

โ— ๋‹ค๋ฅธ Aggregate์— ์†ํ•˜๋Š” ์ƒํ™ฉ

์ƒํ’ˆ ์ •๋ณด์™€ ์‚ฌ์šฉ์ž ๋ฆฌ๋ทฐ๋Š” ๋‹ค๋ฅธ Aggregate์— ์†ํ•œ๋‹ค. ์ƒํ’ˆ ์ •๋ณด๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ์ฃผ์ฒด์™€ ์‚ฌ์šฉ์ž ๋ฆฌ๋ทฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ์ฃผ์ฒด๊ฐ€ ๋‹ค๋ฅด๊ณ  ์„œ๋กœ์˜ ๋ณ€๊ฒฝ์ด ์„œ๋กœ์—๊ฒŒ ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

โœ” Root Aggregate

์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ ์ตœ์ƒ์œ„ ๊ฐ์ฒด๋กœ, Root Aggregate๊ฐ€ Aggregate์˜ ์ƒ๋ช… ์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋ฉฐ, ๋‹ค๋ฅธ ์—”ํ‹ฐํ‹ฐ๋“ค์€ ๋ฃจํŠธ ์—”ํ‹ฐํ‹ฐ์™€ ๊ฐ•ํ•œ ๊ด€๊ณ„๋ฅผ ๊ฐ€์ง€๋ฉฐ ๋ฃจํŠธ ์—”ํ‹ฐํ‹ฐ ์—†์ด๋Š” ์กด์žฌํ•  ์ˆ˜ ์—†๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ƒํ™ฉ์—์„œ OrderItem์— ์ ‘๊ทผํ•˜๋ ค๋ฉด ๋ฐ˜๋“œ์‹œ Order๋ฅผ ํ†ตํ•ด์„œ ์ ‘๊ทผํ•ด์•ผ ํ•œ๋‹ค.

Root Aggregate์˜ ์—ญํ• ์€ Aggregate์˜ ์ผ๊ด€์„ฑ์„ ๊นจ์ง€์ง€ ์•Š๊ฒŒ ํ•˜๋Š” ๊ฒƒ์œผ๋กœ, Aggregate ์™ธ๋ถ€์—์„œ Aggregate์— ์†ํ•œ ๋‚ด๋ถ€ ๊ฐ์ฒด์— ์ง์ ‘ ๋ณ€๊ฒฝํ•˜๋ฉด ์•ˆ๋˜๊ณ , Root Aggregate๋ฅผ ํ†ตํ•ด์„œ ์ ‘๊ทผํ•ด์•ผ ํ•œ๋‹ค.

 

โœ” Aggregate ์ด์ 

โ—ผ ๋„๋ฉ”์ธ ๋ชจ๋ธ์˜ ๋ณต์žก์„ฑ์„ ๊ฐ์†Œ์‹œํ‚จ๋‹ค. -> ์—ฐ๊ด€๋œ ๊ฐ์ฒด๋“ค์„ ๋ฌถ์–ด์„œ ํ•˜๋‚˜์˜ ๊ฐœ๋…์œผ๋กœ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ

โ—ผ ๋„๋ฉ”์ธ ๊ฐ์ฒด์˜ ์ผ๊ด€์„ฑ์„ ๋ณด์žฅํ•œ๋‹ค. -> ๋ฃจํŠธ ์—”ํ‹ฐํ‹ฐ๋ฅผ ํ†ตํ•ด ํ•˜์œ„ ์—”ํ‹ฐํ‹ฐ๋“ค์ด ๊ด€๋ฆฌ๋˜๊ธฐ ๋•Œ๋ฌธ

โ—ผ ๋„๋ฉ”์ธ ๊ฐ์ฒด์˜ ๊ฒฝ๊ณ„๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค. -> Aggregate ์™ธ๋ถ€์—์„œ ๋‚ด๋ถ€ ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ์ ‘๊ทผํ•˜์ง€ ์•Š๋„๋ก ์ œํ•œํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๐Ÿ“’ ์ •๋ฆฌ

โ— ์Šคํ”„๋ง ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํŒจํ‚ค์ง€ ๊ตฌ์กฐ ์„ค๊ณ„ํ•˜๊ธฐ

์™„์ „ํžˆ ์ƒ๋ช… ์ฃผ๊ธฐ๋ฅผ ๊ฐ™์ดํ•˜๊ณ , ํ•จ๊ป˜ ์กฐํšŒ๋˜๊ณ  ์—…๋ฐ์ดํŠธ ๋˜์–ด์•ผ ํ•˜๋Š” ๊ด€๊ณ„, ๋ฃจํŠธ ์—”ํ‹ฐํ‹ฐ ์—†์ด๋Š” ์กด์žฌํ•  ์ˆ˜ ์—†๋Š” ๊ด€๊ณ„๋“ค์€ ํ•˜๋‚˜์˜ Domain ํŒจํ‚ค์ง€ ๋‚ด์—์„œ ์—ฐ๊ด€ ๊ด€๊ณ„๋ฅผ ๋งบ์–ด ๊ฐœ๋ฐœํ•˜๊ณ , Root Aggregate์˜ Repository๋ฅผ ์ด์šฉํ•ด Root Aggregate๋ฅผ ์กฐํšŒํ•œ ํ›„, ์ดํ›„ ํ•˜์œ„ ๋„๋ฉ”์ธ์— ๋Œ€ํ•ด CRUD ์ž‘์—…์„ ์ง„ํ–‰ํ•œ๋‹ค.(CASCADE ์˜ต์…˜ ์‚ฌ์šฉ)

์ด๋Ÿฐ ๊ด€๊ณ„๊ฐ€ ์•„๋‹Œ ๋ถ€๋ถ„์€ ๋‹ค๋ฅธ domain๋‚ด ํŒจํ‚ค์ง€๋กœ ๋งŒ๋“  ํ›„, ์—ฐ๊ด€ ๊ด€๊ณ„๊ฐ€ ์•„๋‹Œ ๊ธฐ๋ณธ ํ‚ค๋ฅผ ๊ฐ–๋Š” ํ˜•ํƒœ๋กœ ์„ค๊ณ„ํ•œ๋‹ค.