Skip to content

Latest commit

ย 

History

History
297 lines (233 loc) ยท 18.8 KB

README.md

File metadata and controls

297 lines (233 loc) ยท 18.8 KB

DDD (Domain-Driven-Design)

DDD start! ๋„๋ฉ”์ธ ์ฃผ๋„ ์„ค๊ณ„ ๊ตฌํ˜„๊ณผ ํ•ต์‹ฌ ๊ฐœ๋… ์ตํžˆ๊ธฐ๋ฅผ ์ฝ์œผ๋ฉฐ ์ •๋ฆฌํ•œ ๋‚ด์šฉ ์ž…๋‹ˆ๋‹ค.

DDD๋ž€ ๋ฌด์—‡์ผ๊นŒ?

๋น„์ฆˆ๋‹ˆ์Šค ๋„๋ฉ”์ธ๋ณ„๋กœ ๊ณตํ†ต์šฉ์–ด(Ubiquitous Language)๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ ๋„๋ฉ”์ธ์˜ ํ”„๋กœ์„ธ์Šค/์ •์ฑ… ๋ณ„๋กœ Context๋ฅผ ๋‚˜๋ˆ„๊ณ , ์ด๋Ÿฌํ•œ Bounded Context๋ฅผ Context Map์œผ๋กœ ๋„์‹ํ™”๋ฅผ ํ•˜๋Š” ์ „๋žต์„ค๊ณ„์™€ Presentation, Service, Domain, Infrastructure ๊ณ„์ธต ๊ตฌ์กฐ๋กœ ์„ค๊ณ„๋ฅผ ํ•˜์—ฌ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜๊ฐ„์˜ ์˜์กด์„ฑ์€ ์ตœ์†Œํ™” ํ•˜๊ณ  ์‘์ง‘๋„๋ฅผ ์ตœ๋Œ€ํ™” ํ•˜๋Š”๊ฒƒ์ด๋‹ค.

1. ๋„๋ฉ”์ธ ๋ชจ๋ธ ์‹œ์ž‘

  • ํ•˜๋‚˜์˜ ๋„๋ฉ”์ธ์€ ํ•˜์œ„์˜ ์—ฌ๋Ÿฌ ๋„๋ฉ”์ธ์œผ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค.
  • ๋„๋ฉ”์ธ ๋งˆ๋‹ค ๊ณ ์ •๋œ ํ•˜์œ„ ๋„๋ฉ”์ธ์ด ์กด์žฌํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.
  • ๋„๋ฉ”์ธ์„ ์–ด๋–ป๊ฒŒ ๊ตฌ์„ฑํ• ์ง€ ์—ฌ๋ถ€๋Š” ์ƒํ™ฉ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง„๋‹ค. ๋„๋ฉ”์ธ์€ ์—ฌ๋Ÿฌ ํ•˜์œ„ ๋„๋ฉ”์ธ์œผ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค.

๋„๋ฉ”์ธ ๋ชจ๋ธ

๊ธฐ๋ณธ์ ์œผ๋กœ ๋„๋ฉ”์ธ ๋ชจ๋ธ์€ ํŠน์ • ๋„๋ฉ”์ธ์„ ๊ฐœ๋…์ ์œผ๋กœ ํ‘œํ˜„ ํ•œ ๊ฒƒ. ์ฆ‰, ๋„๋ฉ”์ธ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜๋ฉด ์—ฌ๋Ÿฌ ๊ด€๊ณ„์ž๋“ค์ด ๋™์ผํ•œ ๋ชจ์Šต์œผ๋กœ ๋„๋ฉ”์ธ์„ ์ดํ•ดํ•˜๊ณ  ๋„๋ฉ”์ธ ์ง€์‹์„ ๊ณต์œ ํ•˜๋Š”๋ฐ ๋„์›€์ด ๋œ๋‹ค.

๋„๋ฉ”์ธ ๋ชจ๋ธ ํ‘œํ˜„ ๋ฐฉ์‹

  • ๊ฐ์ฒด ๊ธฐ๋ฐ˜ ์ฃผ๋ฌธ ๋„๋ฉ”์ธ ๋ชจ๋ธ๋ง (์ฃผ์š” ๋ฐ์ดํ„ฐ ๊ตฌ์„ฑ์„ ํŒŒ์•…ํ•˜๊ณ  ๊ธฐ๋Šฅ๊ณผ ๋ฐ์ดํ„ฐ ๋ณด์—ฌ์ฃผ๊ธฐ ์ ํ•ฉ)
  • ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ, ์ƒํƒœ ๋‹ค์ด์–ด๊ทธ๋žจ์„ ์ด์šฉํ•œ ์ƒํƒœ ๋ชจ๋ธ๋ง
  • ์ด์™ธ์—๋„ ๊ทธ๋ž˜ํ”„ ์ด์šฉํ•œ ๋ชจ๋ธ๋ง ๋“ฑ

๋„๋ฉ”์ธ ๋ชจ๋ธ ํŒจํ„ด

๊ณ„์ธต(์•„ํ‚คํ…์ฒ˜) ๊ตฌ์„ฑ

๊ณ„์ธต(Layer) ์„ค๋ช…
์‚ฌ์šฉ์ž์ธํ„ฐํŽ˜์ด์Šค(UI) ๋˜๋Š” ํ‘œํ˜„(Presentation) ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ์ •๋ณด๋ฅผ ๋ณด์—ฌ์ค€๋‹ค.(Controller)
์‘์šฉ(Application ์‚ฌ์šฉ์ž๊ฐ€ ์š”์ฒญํ•œ ๊ธฐ๋Šฅ์„ ์‹คํ–‰ / ์—…๋ฌด ๋กœ์ง์„ ์ง์ ‘ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์œผ๋ฉฐ ๋„๋ฉ”์ธ ๊ณ„์ธต์„ ์กฐํ•ฉํ•ด ๊ธฐ๋Šฅ์„ ์‹คํ–‰
๋„๋ฉ”์ธ ์‹œ์Šคํ…œ์ด ์ œ๊ณตํ•  ๋„๋ฉ”์ด๋Š์ด ๊ทœ์น™์„ ๊ตฌํ˜„ (Aggregate, Entity)
์ธํ”„๋ผ์ŠคํŠธ๋Ÿญ์ฒ˜(Infrastructure) ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋‚˜ ๋ฉ”์„ธ์ง• ์‹œ์Šคํ…œ๊ณผ ๊ฐ™์€ ์™ธ๋ถ€ ์‹œ์Šคํ…œ๊ณผ์˜ ์—ฐ๋™ ์ฒ˜๋ฆฌ(DB ์—ฐ๋™, Message Queue, SMTP Email, External API)
  • ๋„๋ฉ”์ธ ๋ชจ๋ธ ํŒจํ„ด
    • ํ•ด๋‹น ๋„๋ฉ”์ธ์— ๊ทœ์น™์„ ๊ตฌํ˜„ํ•œ ์ฝ”๋“œ๊ฐ€ ๋„๋ฉ”์ธ ๊ณ„์ธต์— ์œ„์น˜ํ•˜๊ณ , ์ด๋Ÿฐ ๋„๋ฉ”์ธ ๊ทœ์น™์„ ๊ฐ์ฒด ์ง€ํ–ฅ ๊ธฐ๋ฒ•์œผ๋กœ ๊ตฌํ˜„ํ•˜๋Š” ํŒจํ„ด (์„œ๋น„์Šค ๊ณ„์ธต์€ ๋‹จ์ˆœํžˆ ์—”ํ‹ฐํ‹ฐ์— ํ•„์š”ํ•œ ์š”์ฒญ์„ ์œ„์ž„ํ•˜๋Š” ์—ญํ• )
    • ํ•ต์‹ฌ ๊ทœ์น™์„ ๊ตฌํ˜„ํ•œ ์ฝ”๋“œ๋Š” ๋„๋ฉ”์ธ ๋ชจ๋ธ์—๋งŒ ์œ„์น˜ํ•˜๋ฏ€๋กœ, ๊ทœ์น™์ด ๋ฐ”๋€Œ๊ฑฐ๋‚˜ ํ™•์žฅํ•ด์•ผํ•  ๋•Œ ๋‹ค๋ฅธ ์ฝ”๋“œ์— ์˜ํ–ฅ์„ ๋œ ์ฃผ๊ณ  ๋ณ€๊ฒฝ ๋‚ด์—ญ์„ ๋ชจ๋ธ์— ๋ฐ˜์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

cf. ํŠธ๋žœ์žญ์…˜ ์Šคํฌ๋ฆฝํŠธ ํŒจํ„ด

์—”ํ‹ฐํ‹ฐ์—๋Š” ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ๊ฑฐ์˜ ์—†๊ณ  ์„œ๋น„์Šค ๊ณ„์ธต์—์„œ ๋Œ€๋ถ€๋ถ„ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ.

๋„๋ฉ”์ธ ๋ชจ๋ธ ๋„์ถœ

๊ธฐํš์„œ, ์œ ์Šค ์ผ€์ด์Šค, ์‚ฌ์šฉ์ž ์Šคํ† ๋ฆฌ์™€ ๊ฐ™์€ ์š”๊ตฌ ์‚ฌํ•ญ๊ณผ ๊ด€๋ จ์ž๋“ค์˜ ๋Œ€ํ™”๋ฅผ ํ†ตํ•ด ๋„๋ฉ”์ธ์„ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ์ฒซ ์‹œ์ž‘! ๋„๋ฉ”์ธ ๋ชจ๋ธ๋ง ๋•Œ ๋ชจ๋ธ์„ ๊ตฌ์„ฑํ•˜๋Š” ํ•ต์‹ฌ ๊ตฌ์„ฑ์š”์†Œ, ๊ทœ์น™, ๊ธฐ๋Šฅ ์„ ์ฐพ์•„์•ผ ํ•œ๋‹ค.

์—”ํ‹ฐํ‹ฐ์™€ ๋ฐธ๋ฅ˜

๋„๋ฉ”์ธ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์„ค๊ณ„ํ•˜๊ณ  ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์—”ํ‹ฐํ‹ฐ์™€ ๋ฐธ๋ฅ˜์˜ ์ฐจ์ด๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ์ดํ•ดํ•˜๊ณ  ์ œ๋Œ€๋กœ ๊ตฌ๋ถ„ํ•˜๋Š” ๊ฒƒ์ด ๋„๋ฉ”์ธ์„ ๊ตฌํ˜„ํ•˜๋Š”๋ฐ ์žˆ์–ด ์ค‘์š”!

์—”ํ‹ฐํ‹ฐ

์‹๋ณ„์ž๋ฅผ ๊ฐ–๋Š”๋‹ค. (๊ฐ ์—”ํ‹ฐํ‹ฐ๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ์‹๋ณ„์ž๋ฅผ ๊ฐ–๋Š”๋‹ค. ex. ์ฃผ๋ฌธ์€ ๊ฐ ์ฃผ๋ฌธ๋งˆ๋‹ค ์ฃผ๋ฌธ๋ฒˆํ˜ธ๊ฐ€ ๋‹ค๋ฅด๋ฉฐ ์ฃผ๋ฌธ๋ฒˆํ˜ธ ๊ฐ€ ์‹๋ณ„์ž๊ฐ€ ๋จ)

์‹๋ณ„์ž ์ƒ์„ฑ์€ ์‚ฌ์šฉ ๊ธฐ์ˆ ๊ณผ ํŠน์ง•์— ๋”ฐ๋ผ ๋‹ค๋ฅด๋‚˜ ํ”ํžˆ ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•œ๋‹ค. (โš  ๊ฐ™์€ ์‹œ๊ฐ„์— ๋™์‹œ์— ์‹๋ณ„์ž๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ๊ฐ™์€ ์‹๋ณ„์ž๊ฐ€ ๋งŒ๋“ค์–ด์ง€๋ฉด ์•ˆ๋œ๋‹ค.)

  • ํŠน์ • ๊ทœ์น™์— ๋”ฐ๋ผ ์ƒ์„ฑ
  • UUID ์‚ฌ์šฉ
  • ๊ฐ’์„ ์ง์ ‘ ์ž…๋ ฅ
  • ์ผ๋ จ๋ฒˆํ˜ธ ์‚ฌ์šฉ(Oracle ์‹œํ€€์Šค๋‚˜ MySQL ์ž๋™ ์ฆ๊ฐ€ ์ปฌ๋Ÿผ ์‚ฌ์šฉ)
๋ฐธ๋ฅ˜

๊ฐœ๋…์ ์œผ๋กœ ์™„์ „ํ•œ ํ•˜๋‚˜๋ฅผ ํ‘œํ˜„ํ•  ๋•Œ ์‚ฌ์šฉ (ex. ์ฃผ์†Œ = address1, address2, zipCode)

์žฅ์ )

  • ์ฝ”๋“œ์˜ ์˜๋ฏธ๋ฅผ ๋” ์ž˜ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค. (๊ฐœ๋…์ ์œผ๋กœ ํ‘œํ˜„๋œ ๊ฒƒ์„ ์‚ฌ์šฉํ•ด ์˜๋ฏธ๋ฅผ ํŒŒ์•…ํ•˜๊ธฐ ์‰ฌ์›€)
  • ๋ฐธ๋ฅ˜ ํƒ€์ž…์„ ์œ„ํ•œ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ฐธ๋ฅ˜ ๊ฐ์ฒด์˜ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝํ•  ๋•Œ ๊ธฐ์กด ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ ๋ณด๋‹ค ๋ณ€๊ฒฝํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ–๋Š” ์ƒˆ๋กœ์šด ๋ฐธ๋ฅ˜ ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐฉ์‹ ์„ ํ˜ธ. ๋ถˆ๋ณ€ ๊ฐ์ฒด (๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š” ํƒ€์ž…)๋กœ ๊ตฌํ˜„ํ•˜๊ฒŒ ๋˜๋ฉด ๋ณด๋‹ค ์•ˆ์ „ํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ถˆ๋ณ€ ๊ฐ์ฒด๋Š” ์ฐธ์กฐ ํˆฌ๋ช…์„ฑ๊ณผ ์Šค๋ ˆ๋“œ์— ์•ˆ์ „ํ•˜๋‹ค.

๋„๋ฉ”์ธ ๋ชจ๋ธ์— set ๋ฉ”์„œ๋“œ ๋„ฃ์ง€ ์•Š๊ธฐ

set ๋ฉ”์„œ๋“œ๋Š” ๋„๋ฉ”์ธ์˜ ํ•ต์‹ฌ ๊ฐœ๋…์ด๋‚˜ ์˜๋„๋ฅผ ์ฝ”๋“œ์—์„œ ์‚ฌ๋ผ์ง€๊ฒŒ ํ•œ๋‹ค. ๋˜ํ•œ, ๋„๋ฉ”์ธ ๊ฐ์ฒด ์ƒ์„ฑ ์‹œ ์™„์ „ํ•œ ์ƒํƒœ๊ฐ€ ์•„๋‹ ์ˆ˜๋„ ์žˆ๋‹ค. ๋„๋ฉ”์ธ ๊ฐ์ฒด๊ฐ€ ๋ถˆ์™„์ „ํ•œ ์ƒํƒœ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ ๋ฐฉ์ง€ ํ•˜๋ ค๋ฉด ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ๋‘ ๋ฐ›์•„์•ผ ํ•œ๋‹ค.

2. ์•„ํ‚คํ…์ฒ˜ ๊ฐœ์š”

๊ณ„์ธต ๊ตฌ์กฐ ์•„ํ‚คํ…์ฒ˜

Application(service) -> Domain(entity) -> Infrastructure(DB, rule Engine, messaging)
Application(service) -> Infrastructure(DB, rule Engine, messaging)
Domain(entity) -> Infrastructure(DB, rule Engine, messaging)
  • ํŠน์„ฑ์ƒ ์ƒ์œ„ ๊ณ„์ธต์—์„œ ํ•˜์œ„ ๊ณ„์ธต์œผ๋กœ์˜ ์˜์กด๋งŒ ์กด์žฌ, ํ•˜์œ„ ๊ณ„์ธต์€ ์ƒ์œ„ ๊ณ„์ธต์— ์˜์กดํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • ํ•˜์ง€๋งŒ, ๊ตฌํ˜„์˜ ํŽธ๋ฆฌํ•จ์„ ์œ„ํ•ด ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ์œ ์—ฐํ•˜๊ฒŒ ์ ์šฉํ•œ๋‹ค. (ex. ์‘์šฉ ๊ณ„์ธต์€ ๋„๋ฉ”์ธ ๊ณ„์ธต์— ์˜์กดํ•˜์ง€๋งŒ ์™ธ๋ถ€ ์‹œ์Šคํ…œ๊ณผ์˜ ์—ฐ๋™์„ ์œ„ํ•ด ๋” ์•„๋ž˜ ๊ณ„์ธต์ธ ์ธํ”„๋ผ์ŠคํŠธ๋Ÿญ์ฒ˜ ๊ณ„์ธต์— ์˜์กดํ•˜๊ธฐ๋„ ํ•จ.)

โœ… ์ธํ”„๋ผ์ŠคํŠธ๋Ÿญ์ฒ˜์— ์˜์กดํ•˜๋ฉด, ํ…Œ์ŠคํŠธ์˜ ์–ด๋ ค์›€ ๊ณผ ๊ธฐ๋Šฅ ํ™•์žฅ์˜ ์–ด๋ ค์›€ ์˜ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด.. ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์„๊นŒ? ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€? DIP ์ ์šฉํ•˜๋Š” ๊ฒƒ

DIP (Dependency Inversion Principle) : ์˜์กด์„ฑ ์—ญ์ „์˜ ๋ฒ•์น™ ์ƒ์œ„ ๊ณ„์ธต์ด ํ•˜์œ„ ๊ณ„์ธต์— ์˜์กดํ•˜๋Š” ์˜์กด ๊ด€๊ณ„๋ฅผ ์—ญ์ „(๋ฐ˜์ „) ์‹œํ‚ด์œผ๋กœ์จ ์ƒ์œ„ ๊ณ„์ธต์ด ํ•˜์œ„ ๊ณ„์ธต์˜ ๊ตฌํ˜„์œผ๋กœ ๋ถ€ํ„ฐ ๋…๋ฆฝ๋˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ถ”์ƒํ™” ํ•˜์—ฌ ๊ด€๊ณ„๋ฅผ ๋Š์Šจํ•˜๊ฒŒ ๋งŒ๋“ค๊ณ  ํ™•์žฅ์— ์œ ์—ฐํ•˜๊ฒŒ ๋งŒ๋“ ๋‹ค.

ex. DIP๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ธฐ๋ฒ• ์ค‘ ํ•˜๋‚˜๊ฐ€ DI (Dependency Injection) ์ด๋‹ค.

  • DIP๋Š” ๊ณ ์ˆ˜์ค€ ๋ชจ๋“ˆ์€ ๋” ์ด์ƒ ์ €์ˆ˜์ค€ ๋ชจ๋“ˆ์— ์˜์กดํ•˜์ง€ ์•Š๊ณ  ๊ตฌํ˜„์„ ์ถ”์ƒํ™”ํ•œ ์ธํ„ฐํŽ˜์ด์Šค์— ์˜์กดํ•œ๋‹ค.

  • ์‹ค์ œ ์‚ฌ์šฉํ•  ์ €์ˆ˜์ค€ ๊ตฌํ˜„ ๊ฐ์ฒด๋Š” ์˜์กด ์ฃผ์ž…์„ ์ด์šฉํ•ด์„œ ์ „๋‹ฌ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

  • DIP ์ ์šฉํ•  ๋•Œ ์ค‘์š”ํ•œ ์ !!

    • ํ•˜์œ„ ๊ธฐ๋Šฅ์„ ์ถ”์ƒํ™”ํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๊ณ ์ˆ˜์ค€ ๋ชจ๋“ˆ ๊ด€์ ์—์„œ ๋„์ถœํ•œ๋‹ค. (์ถ”์ƒํ™”ํ•œ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๊ณ ์ˆ˜์ค€ ๋ชจ๋“ˆ์— ์œ„์น˜)

๋„๋ฉ”์ธ ์˜์—ญ์˜ ๊ตฌ์„ฑ์š”์†Œ

  • ๋„๋ฉ”์ธ ์˜์—ญ์˜ ๋ชจ๋ธ์€ ๋„๋ฉ”์ธ์˜ ์ฃผ์š” ๊ฐœ๋…์„ ํ‘œํ˜„ํ•˜๋ฉฐ ํ•ต์‹ฌ์ด ๋˜๋Š” ๋กœ์ง์„ ๊ตฌํ˜„ํ•œ๋‹ค.
์š”์†Œ ์„ค๋ช…
์—”ํ‹ฐํ‹ฐ (Entity) ๊ณ ์œ ์˜ ์‹๋ณ„์ž๋ฅผ ๊ฐ–๋Š” ๊ฐ์ฒด๋กœ ์ž์‹ ์˜ ๋ผ์ดํ”„ ์‚ฌ์ดํด์„ ๊ฐ–๋Š”๋‹ค. ๋„๋ฉ”์ธ ๋ชจ๋ธ์˜ ํ…Œ์ดํ„ฐ๋ฅผ ํฌํ•จํ•˜๋ฉฐ ํ•ด๋‹น ๋ฐ์ดํ„ฐ์™€ ๊ด€๋ จ๋œ ๊ธฐ๋Šฅ์„ ํ•จ๊ป˜ ์ œ๊ณต (ํšŒ์›, ์ƒํ’ˆ ๊ฐ™ใ…‡๋ฅธ ๋„๋ฉ”์ธ์˜ ๊ณ ์œ ํ•œ ๊ฐœ๋… ํ‘œํ˜„)
๋ฐธ๋ฅ˜ (Value) ๊ณ ์œ ์˜ ์‹๋ณ„์ž๋ฅผ ๊ฐ–์ง€ ์•Š๋Š” ๊ฐ์ฒด, ๊ฐœ๋…์ ์œผ๋กœ ํ•˜๋‚˜์ธ ๋„๋ฉ”์ธ ๊ฐ์ฒด์˜ ์†์„ฑ์„ ํ‘œํ˜„ํ•  ๋•Œ ์‚ฌ์šฉ. (์ฃผ์†Œ, ๊ตฌ๋งค ๊ธˆ์•ก์„ ์œ„ํ•œ ๊ธˆ์•ก(Money) ๊ฐ™์€ ํƒ€์ž…)
์• ๊ทธ๋ฆฌ๊ฑฐํŠธ (Aggregate) ๊ด€๋ จ๋œ ์—”ํ‹ฐํ‹ฐ์™€ ๋ฐธ๋ฅ˜ ๊ฐ์ฒด๋ฅผ ๊ฐœ๋…์ ์œผ๋กœ ํ•˜๋‚˜๋กœ ๋ฌถ์€ ๊ฒƒ. (์ฃผ๋ฌธ ๊ด€๋ จ๋œ Order ์—”ํ‹ฐํ‹ฐ, OrderLine ๋ฐธ๋ฅ˜, Orderer ๋ฐธ๋ฅ˜ ๊ฐ์ฒด => ์ฃผ๋ฌธ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ)
๋ ˆํŒŒ์ง€ํ† ๋ฆฌ (Repository) ๋„๋ฉ”์ธ ๋ชจ๋ธ์˜ ์˜์†์„ฑ์„ ์ฒ˜๋ฆฌ. (DBMS ํ…Œ์ด๋ธ”์—์„œ ์—”ํ‹ฐํ‹ฐ ๊ฐ์ฒด๋ฅผ ๋กœ๋”ฉํ•˜๊ฑฐ๋‚˜ ์ €์žฅํ•˜๋Š” ๊ธฐ๋Šฅ ์ œ๊ณต)
๋„๋ฉ”์ธ ์„œ๋น„์Šค (Domain Service) ํŠน์ • ์—”ํ‹ฐํ‹ฐ์— ์†ํ•˜์ง€ ์•Š๋Š” ๋„๋ฉ”์ธ ๋กœ์ง ์ œ๊ณต. ๋„๋ฉ”์ธ ๋กœ์ง์ด ์—ฌ๋Ÿฌ ์—”ํ‹ฐํ‹ฐ์™€ ๋ฐธ๋ฅ˜๋ฅผ ํ•„์š”๋กœ ํ•  ๊ฒฝ์šฐ ๋„๋ฉ”์ธ ์„œ๋น„์Šค์—์„œ ๋กœ์ง์„ ๊ตฌํ˜„ํ•œ๋‹ค. (ex. ํ• ์ธ ๊ธˆ์•ก ๊ณ„์‚ฐ ์ฟ ํฐ, ํšŒ์› ๋“ฑ๊ธ‰, ๊ตฌ๋งค ๊ธˆ์•ก ๋“ฑ ๋‹ค์–‘ํ•œ ์กฐ๊ฑด์„ ์ด์šฉํ•ด์„œ ๊ตฌํ˜„ํ•ด์•ผ ํ•  ๊ฒฝ์šฐ)

์—”ํ‹ฐํ‹ฐ (Entity) ์™€ ๋ฐธ๋ฅ˜ (Value)

  • ์ฐจ์ด์ 
    • ๋„๋ฉ”์ธ ๋ชจ๋ธ์˜ ์—”ํ‹ฐํ‹ฐ: ๋ฐ์ดํ„ฐ์™€ ํ•จ๊ป˜ ๋„๋ฉ”์ธ ๊ธฐ๋Šฅ์„ ํ•จ๊ป˜ ์ œ๊ณตํ•˜๋Š” ๊ฐ์ฒด
      • ๋„๋ฉ”์ธ ๊ด€์ ์—์„œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ณ  ๊ธฐ๋Šฅ ๊ตฌํ˜„์„ ์บก์Šํ™” ํ•ด์„œ ์ž„์˜๋กœ ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒƒ์„ ๋ง‰๋Š”๋‹ค.
      • ์ฃผ๋ฌธ ์—”ํ‹ฐํ‹ฐ์˜ ๊ฒฝ์šฐ, ์ฃผ๋ฌธ ๊ด€๋ จ๋œ ๋ฐ์ดํ„ฐ ๋ฟ ์•„๋‹ˆ๋ผ ๋ฐฐ์†ก์ง€ ์ฃผ์†Œ ๋ณ€๊ฒฝ์„ ์œ„ํ•œ ๊ธฐ๋Šฅ๋„ ํ•จ๊ป˜ ์ œ๊ณต
    • ๋‘ ๊ฐœ ์ด์ƒ์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๊ฐœ๋…์ ์œผ๋กœ ํ•˜๋‚˜์ธ ๊ฒฝ์šฐ ๋ฐธ๋ฅ˜ ํƒ€์ž…์œผ๋กœ ํ‘œํ˜„ ๊ฐ€๋Šฅ (๋ฐธ๋ฅ˜๋Š” ๋ถˆํŽธ์œผ๋กœ ๊ตฌํ˜„ ๊ถŒ์žฅ)

์• ๊ทธ๋ฆฌ๊ฑฐํŠธ (Aggregate)

  • ๋„๋ฉ”์ธ ๋ชจ๋ธ์—์„œ ์ „์ฒด ๊ตฌ์กฐ๋ฅผ ์ดํ•ดํ•˜๊ณ  ๋ณต์žกํ•œ ๋„๋ฉ”์ธ ๋ชจ๋ธ์„ ๊ด€๋ฆฌํ•˜๋Š”๋ฐ ๋„์›€์ด ๋œ๋‹ค.

  • ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ ๊ตฌํ˜„ ์‹œ ๊ณ ๋ คํ•ด์•ผํ•  ๊ฒƒ์ด ๋งŽ๋‹ค. ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ๋ฅผ ์–ด๋–ป๊ฒŒ ๊ตฌ์„ฑํ–ˆ๋Š๋ƒ์— ๋”ฐ๋ผ ๊ตฌํ˜„์ด ๋ณต์žกํ•ด์ง€๊ธฐ๋„ ํ•˜๊ณ , ํŠธ๋žœ์žญ์…˜ ๋ฒ”์œ„๊ฐ€ ๋‹ฌ๋ผ์ง€๊ธฐ๋„ ํ•˜๊ธฐ ๋•Œ๋ฌธ

  • ์„ ํƒํ•œ ๊ตฌํ˜„ ๊ธฐ์ˆ ์— ๋”ฐ๋ผ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ ๊ตฌํ˜„์— ์ œ์•ฝ์ด ์ƒ๊ธฐ๊ธฐ๋„ ํ•œ๋‹ค.

  • ๋ชจ๋ธ์„ ์ดํ•ดํ•˜๋Š”๋ฐ ๋„์›€์„ ์ฃผ๋ฉฐ, ์ผ๊ด€์„ฑ์„ ๊ด€๋ฆฌํ•˜๋Š” ๊ธฐ์ค€

    • ์ˆ˜ ๋งŽ์€ ๊ฐ์ฒด๋ฅผ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ๋กœ ๋ฌถ์–ด์„œ ๋ฐ”๋ผ๋ณด๋ฉด ์ข€ ๋” ์ƒ์œ„ ์ˆ˜์ค€์—์„œ ๋„๋ฉ”์ธ ๋ชจ๋ธ ๊ฐ„์˜ ๊ด€๊ณ„๋ฅผ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ ๊ฒฝ๊ณ„
      • ํ•œ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ์— ์†ํ•œ ๊ฐ์ฒด๋Š” ๋‹ค๋ฅธ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ์— ์†ํ•˜์ง€ ์•Š๋Š”๋‹ค.
      • ๊ฒฝ๊ณ„ ์„ค์ •์˜ ๊ธฐ๋ณธ์€ ๋„๋ฉ”์ธ ๊ทœ์น™๊ณผ ์š”๊ตฌ์‚ฌํ•ญ -> ๋„๋ฉ”์ธ ๊ทœ์น™์— ๋”ฐ๋ผ ํ•จ๊ฒŒ ์ƒ์„ฑ๋˜๋Š” ๊ตฌ์„ฑ์š”์†Œ๋Š” ํ•œ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ์— ์†ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๋‹ค. ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ๋Š” ๋ณต์žกํ•œ ๋ชจ๋ธ์„ ๊ด€๋ฆฌํ•˜๋Š” ๊ธฐ์ค€ ์ œ๊ณต
  • ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ ๋ฃจํŠธ (์• ๊ทธ๋ฆฌ๊ฑฐํŠธ ๋ฃจํŠธ ์—”ํ‹ฐํ‹ฐ)

    • ํ•ต์‹ฌ ์—ญํ• ) ๋„๋ฉ”์ธ ๊ทœ์น™์— ๋”ฐ๋ผ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ์˜ ์ผ๊ด€์„ฑ์ด ๊นจ์ง€์ง€ ์•Š๋„๋ก ํ•œ๋‹ค.

      • ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ์— ์†ํ•ด ์žˆ๋Š” ์—”ํ‹ฐํ‹ฐ์™€ ๋ฐธ๋ฅ˜ ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด์„œ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ๊ฐ€ ๊ตฌํ˜„ํ•ด์•ผ ํ•  ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.
    • ๊ฐ„์ ‘์ ์œผ๋กœ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ ๋‚ด์˜ ๋‹ค๋ฅธ ์—”ํ‹ฐํ‹ฐ๋‚˜ ๋ฐธ๋ฅ˜ ๊ฐ์ฒด์— ์ ‘๊ทผํ•˜๊ฒŒ ๋œ๋‹ค. ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ ๋‹จ์œ„๋กœ ๊ตฌํ˜„ -> ๋‚ด๋ถ€ ๊ตฌํ˜„์„ ์ˆจ๊ฒจ ์บก์Šํ™” ํ•˜๋„๋ก ํ•œ๋‹ค.

    • ๋„๋ฉ”์ธ ๋กœ์ง์— ๋งž๊ฒŒ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ์˜ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌ

    • ๋ถˆ ํ•„์š”ํ•œ ์ค‘๋ณต์„ ํ”ผํ•˜๊ณ  ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ ๋ฃจํŠธ๋ฅผ ํ†ตํ•ด์„œ๋งŒ ๋„๋ฉ”์ธ ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๊ฒŒ ํ•˜๋ ค๋ฉด?

      • ๋‹จ์ˆœํžˆ ํ•„๋“œ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” set ๋ฉ”์„œ๋“œ๋ฅผ ๊ณต๊ฐœ(public) ๋ฒ”์œ„๋กœ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค. (๋„๋ฉ”์ธ ๋ชจ๋ธ์—์„œ ๊ณต๊ฐœ set ๋ฉ”์„œ๋“œ๋Š” ๊ฐ€๊ธ‰์  ํ”ผํ•œ๋‹ค.)
        • ๋„๋ฉ”์ธ ๋ชจ๋ธ์˜ ์—”ํ‹ฐํ‹ฐ ๋‚˜ ๋ฐธ๋ฅ˜ ์— ๊ณต๊ฐœ set ๋ฉ”์„œ๋“œ๋งŒ ๋„ฃ์ง€ ์•Š์•„๋„ ์ผ๊ด€์„ฑ ๊นจ์งˆ ๊ฐ€๋Šฅ์„ฑ ์ค„์–ด๋“ ๋‹ค.
      • ๋ฐธ๋ฅ˜ ํƒ€์ž…์€ ๋ถˆ๋ณ€์œผ๋กœ ๊ตฌํ˜„ํ•œ๋‹ค.
        • ๋ถˆ๋ณ€ ๋ฐธ๋ฅ˜ ๊ฐ์ฒด์˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด, ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ํ• ๋‹นํ•ด์„œ ๋ณ€๊ฒฝํ•ด์•ผ ํ•œ๋‹ค.
        • ๋ฐธ๋ฅ˜ ํƒ€์ž…์˜ ๋‚ด๋ถ€ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ ๋ฃจํŠธ๋ฅผ ํ†ตํ•ด์„œ๋งŒ ๊ฐ€๋Šฅํ•˜๋‹ค. -> ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ ์ „์ฒด์˜ ์ผ๊ด€์„ฑ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Œ!

๋ ˆํŒŒ์ง€ํ† ๋ฆฌ (Repository)

  • ๋„๋ฉ”์ธ ๊ฐ์ฒด๋ฅผ ์ง€์†์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋ ค๋ฉด RDBMS, NoSQL, ๋กœ์ปฌ ํŒŒ์ผ๊ณผ ๊ฐ™์€ ๋ฌผ๋ฆฌ์ ์ธ ์ €์žฅ์†Œ์— ๋„๋ฉ”์ธ ๊ฐ์ฒด๋ฅผ ๋ณด๊ด€ํ•ด์•ผ ํ•œ๋‹ค. (์ด๋ฅผ ์œ„ํ•œ ๋„๋ฉ”์ธ ๋ชจ๋ธ = ๋ ˆํŒŒ์ง€ํ† ๋ฆฌ)

  • ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ ๋‹จ์œ„๋กœ ๋„๋ฉ”์ธ ๊ฐ์ฒด๋ฅผ ์ €์žฅํ•˜๊ณ  ์กฐํšŒํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ •์˜ํ•œ๋‹ค.

  • ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ๋Š” ๊ฐœ๋…์ ์œผ๋กœ ํ•˜๋‚˜๋กœ ๋ ˆํŒŒ์ง€ํ† ๋ฆฌ๋Š” ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ ์ „์ฒด๋ฅผ ์ €์žฅ์†Œ์— ์˜์†ํ™” ํ•ด์•ผํ•œ๋‹ค.

    • Order ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ์™€ ๊ด€๋ จ๋œ ํ…Œ์ด๋ธ”์ด ์„ธ๊ฐœ ๋ผ๋ฉด ๋ ˆํŒŒ์ง€ํ† ๋ฆฌ๋ฅผ ํ†ตํ•ด์„œ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ ๋ฃจํŠธ์™€ ๋งคํ•‘๋œ ํ…Œ์ด๋ธ” ๋ฟ ์•„๋‹ˆ๋ผ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ์— ์†ํ•œ ๋ชจ๋“  ๊ตฌ์„ฑ์š”์†Œ๋ฅผ ์œ„ํ•œ ํ…Œ์ด๋ธ”์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•ด์•ผ ํ•œ๋‹ค.
    • ex) Order ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ๋Š” OrderLine, Orderer ๋“ฑ ๋ชจ๋“  ๊ตฌ์„ฑ ์š”์†Œ ํฌํ•จ ํ•ด์•ผ ํ•จ.
  • repository interface ๋Š” ๋„๋ฉ”์ธ ๋ชจ๋ธ ์˜์—ญ์— ์†ํ•˜๋ฉฐ, ์‹ค์ œ ๊ตฌํ˜„ ํด๋ž˜์Šค๋Š” infrastructure ์˜์—ญ์— ์†ํ•œ๋‹ค.

  • ์–ด๋–ค ๊ธฐ์ˆ ์„ ์ด์šฉํ•ด์„œ ๋ ˆํŒŒ์ง€๋กœํ‹ฐ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š๋ƒ์— ๋”ฐ๋ผ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ์˜ ๊ตฌํ˜„๋„ ์˜ํ–ฅ์„ ๋ฐ›๋Š”๋‹ค.

    • ex) ORM ๊ธฐ์ˆ  ์ค‘ JPA/Hibernate ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด, ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค ๊ด€๊ณ„ํ˜• ๋ชจ๋ธ์— ๊ฐ์ฒด ๋„๋ฉ”์ธ ๋ชจ๋ธ์„ ๋งž์ถฐ์•ผํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค.

์ธํ”„๋ผ์ŠคํŠธ๋Ÿญ์ฒ˜ (Infrastructure) ๊ฐœ์š”

  • ํ‘œํ˜„ ์˜์—ญ, ์‘์šฉ ์˜์—ญ, ๋„๋ฉ”์ธ ์˜์—ญ ์ง€์›
  • ๋„๋ฉ”์ธ ๊ฐ์ฒด์˜ ์˜์†์„ฑ ์ฒ˜๋ฆฌ, ํŠธ๋žœ์žญ์…˜, SMTP Client, REST Client ๋“ฑ ๋‹ค๋ฅธ ์˜์—ญ์—์„œ ํ•„์š”๋กœํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ, ๊ตฌํ˜„ ๊ธฐ์ˆ , ๋ณด์กฐ ๊ธฐ๋Šฅ ์ง€์›
  • ๋„๋ฉ”์ธ ์˜์—ญ๊ณผ ์‘์šฉ ์˜์—ญ์—์„œ ์ธํ”„๋ผ์ŠคํŠธ๋Ÿญ์ฒ˜์˜ ๊ธฐ๋Šฅ์„ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค, ๋‘ ์˜์—ญ์— ์ •์˜ํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ธํ”„๋ผ์ŠคํŠธ๋Ÿญ์ฒ˜ ์˜์—ญ์— ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ์‹œ์Šคํ…œ์„ ๋” ์œ ์—ฐํ•˜๊ณ  ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ค์–ด ์ค€๋‹ค. - DIP

โœ… DIP ๊ฐ€ ์ฃผ๋Š” ๊ตฌํ˜„์˜ ํŽธ๋ฆฌํ•จ ์žฅ์  ๋งŒํผ DIP์˜ ์žฅ์ ์„ ํ•ด์น˜์ง€ ์•Š๋Š” ๋ฒ”์œ„์—์„œ ์‘์šฉ ์˜์—ญ๊ณผ ๋„๋ฉ”์ธ ์˜์—ญ์—์„œ ๊ตฌํ˜„ ๊ธฐ์ˆ ์— ๋Œ€ํ•œ ์˜์กด์„ ๊ฐ€์ ธ๊ฐ€๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. (์ธํ”„๋ผ์ŠคํŠธ๋Ÿญ์ฒ˜์˜ ์˜์กด์„ฑ์„ ์—†์• ๋Š” ๊ฒƒ์œผ๋กœ ์ž์นซ ๊ตฌํ˜„์„ ๋” ๋ณต์žกํ•˜๊ณ  ์–ด๋ ต๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ!) ex, @Transactional

๋ชจ๋“ˆ ๊ตฌ์„ฑ

  • ๋„๋ฉ”์ธ์ด ํฌ๋ฉด ํ•˜์œ„ ๋„๋ฉ”์ธ์œผ๋กœ ๋‚˜๋ˆ„๊ณ , ๊ฐ ํ•˜์œ„ ๋„๋ฉ”์ธ๋งˆ๋‹ค ๋ณ„๋„ ํŒจํ‚ค์ง€๋ฅผ ๊ตฌ์„ฑํ•œ๋‹ค.

  • domain ๋ชจ๋“ˆ์€ ๋„๋ฉ”์ธ์— ์†ํ•œ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ ๊ธฐ์ค€์œผ๋กœ ํŒจํ‚ค์ง€๋ฅผ ๊ตฌ์„ฑํ•œ๋‹ค.

  • ๊ฐ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ์™€ ๋ชจ๋ธ๊ณผ ๋ ˆํŒŒ์ง€ํ† ๋ฆฌ๋Š” ๊ฐ™์€ ํŒจํ‚ค์ง€์— ์œ„์น˜์‹œํ‚จ๋‹ค.

  • ๋„๋ฉ”์ธ์ด ๋ณต์žกํ•˜๋ฉด ๋„๋ฉ”์ธ ๋ชจ๋ธ๊ณผ ๋„๋ฉ”์ธ ์„œ๋น„์Šค๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณ„๋„ ํŒจํ‚ค์ง€์— ์œ„์น˜ ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

com.hyeon.order.domain.order: ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ ์œ„์น˜
com.hyeon.order.domain.service: ๋„๋ฉ”์ธ ์„œ๋น„์Šค ์œ„์น˜
  • ์‘์šฉ ์„œ๋น„์Šค๋„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋„๋ฉ”์ธ ๋ณ„๋กœ ํŒจํ‚ค์ง€ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค.
com.hyeon.catalog.application.product
com.hyeon.catalog.application.category

3. ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ

ํŠธ๋žœ์žญ์…˜ ๋ฒ”์œ„

  • ํŠธ๋žœ์žญ์…˜ ๋ฒ”์œ„๋Š” ์ž‘์„ ์ˆ˜๋ก ์ข‹๋‹ค.
    • DB ๊ธฐ์ค€์œผ๋กœ ํ•œ ํŠธ๋žœ์žญ์…˜์ด ํ•œ ๊ฐœ์˜ ํ…Œ์ด๋ธ”์„ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ๊ณผ ์„ธ ๊ฐœ์˜ ํ…Œ์ด๋ธ” ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ์€ ์„ฑ๋Šฅ์—์„œ ์ฐจ์ด ๋ฐœ์ƒ
    • ํ•œ ํŠธ๋žœ์žญ์…˜์— ๋‘๊ฐœ ์ด์ƒ์˜ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด ํŠธ๋žœ์žญ์…˜ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์œผ๋ฉฐ, ๊ฐœ์ˆ˜๊ฐ€ ๋งŽ์•„์งˆ ์ˆ˜๋ก ์ฒ˜๋ฆฌ๋Ÿ‰๋„ ๋–จ์ด์ง€๊ฒŒ ๋œ๋‹ค.
  • ํ•œ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ์—์„œ ๋‹ค๋ฅธ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ์˜ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝ ํ•˜๋Š” ๊ฒƒ์€ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ ๊ฐ„์˜ ์˜์กด ๊ฒฐํ•ฉ๋„๋ฅผ ๋†’์—ฌ ๊ฒฐ๊ณผ์ ์œผ๋กœ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ์˜ ๋ณ€๊ฒฝ์„ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ ๋‹ค.

ID๋ฅผ ์ด์šฉํ•œ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ ์ฐธ์กฐ

ํ•„๋“œ๋ฅผ ์ด์šฉํ•ด ๋‹ค๋ฅธ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ๋ฅผ ์ง์ ‘ ์ฐธ์กฐํ•˜๋Š” ๊ฒƒ์€ ๊ฐœ๋ฐœ์ž์˜ ๊ตฌํ˜„์˜ ํŽธ๋ฆฌํ•จ์„ ์ œ๊ณตํ•œ๋‹ค. ํ•˜์ง€๋งŒ, ํŽธํ•œ ํƒ์ƒ‰ ์˜ค์šฉ, ์„ฑ๋Šฅ์— ๋Œ€ํ•œ ๊ณ ๋ฏผ, ํ™•์žฅ์˜ ์–ด๋ ค์›€ ๋ฌธ์ œ๋ฅผ ์•ผ๊ธฐ ์‹œํ‚จ๋‹ค. ID๋ฅผ ์ด์šฉํ•ด์„œ ๋‹ค๋ฅธ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ๋ฅผ ์ฐธ์กฐ ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์„ธ๊ฐ€์ง€ ๋ฌธ์ œ๋ฅผ ์™„ํ™” ์‹œํ‚จ๋‹ค.

ID๋ฅผ ์ด์šฉํ•œ ์ฐธ์กฐ์™€ ์กฐํšŒ ์„ฑ๋Šฅ

ID๋ฅผ ์ด์šฉํ•œ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ ์ฐธ์กฐ๋Š” ์ง€์—ฐ ๋กœ๋”ฉ๊ณผ ๊ฐ™์€ ํšจ๊ณผ๋ฅผ ๋งŒ๋“œ๋Š”๋ฐ ์ง€์—ฐ ๋กœ๋”ฉ๊ณผ ๊ด€๋ จ๋œ ๋Œ€ํ‘œ์ ์ธ ๋ฌธ์ œ๊ฐ€ N + 1 ์กฐํšŒ ๋ฌธ์ œ ์ด๋‹ค.

N + 1 ์กฐํšŒ ๋ฌธ์ œ

์กฐํšŒ ๋Œ€์ƒ์ด N ๊ฐœ ์ผ ๋•Œ N ๊ฐœ๋ฅผ ์ฝ์–ด์˜ค๋Š” ํ•œ๋ฒˆ์˜ ์ฟผ๋ฆฌ์™€ ์—ฐ๊ด€๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด์˜ค๋Š” ์ฟผ๋ฆฌ๋ฅผ N๋ฒˆ ์‹คํ–‰ ํ•˜๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค. ์ด๋Š” ๋” ๋งŽ์€ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•ด์„œ ์ „์ฒด ์กฐํšŒ ์†๋„๊ฐ€ ๋Š๋ ค์ง€๋Š” ์›์ธ์ด ๋œ๋‹ค.

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ์กฐ์ธ์„ ์‚ฌ์šฉ ํ•œ๋‹ค.

  • ID ์ฐธ์กฐ ๋ฐฉ์‹ -> ๊ฐ์ฒด ์ฐธ์กฐ ๋ฐฉ์‹ ๋ณ€๊ฒฝ ํ•˜๊ณ  ์ฆ‰์‹œ๋กœ๋”ฉ์„ ์‚ฌ์šฉํ•˜๋„๋ก ๋งคํ•‘ ์„ค์ •์„ ๋ฐ”๊พธ๋Š” ๊ฒƒ.
  • ID ์ฐธ์กฐ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋ฉด์„œ N+1 ์กฐํšŒ ๋ฌธ์ œ๋ฅผ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š”? ์„ธํƒ€ ์กฐ์ธ์„ ์ด์šฉํ•ด์„œ ์ „์šฉ ์กฐํšŒ ์ฟผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
  • JPA์—์„œ ์กฐํšŒ ์ „์šฉ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰
  • CQRS

์• ๊ทธ๋ฆฌ๊ฑฐํŠธ ๊ฐ„ ์ง‘ํ•ฉ ์—ฐ๊ด€

JPA ์ด์šฉํ•œ ๋งคํ•‘ ์„ค์ •์œผ๋กœ ID ์ฐธ์กฐ๋กœ ์ด์šฉํ•œ M:N ๋‹จ๋ฐฉํ–ฅ ์—ฐ๊ด€ ๊ตฌํ˜„ ๊ฐ€๋Šฅ.

@Entity
@Table(name = "product")
public class Product {

    @EmbeddedId
    private ProductId id;
    
    @ElementCollection
    @CollectionTable(name = "product_category",
                joinColumns = @JoingColumn(name = "product_id"))
    private Set<CategoryId> categoryIds;
    ...
}

์• ๊ทธ๋ฆฌ๊ฑฐํŠธ๋ฅผ ํŒฉํ† ๋ฆฌ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ

์• ๊ทธ๋ฆฌ๊ฑฐํŠธ๋ฅผ ํŒฉํ† ๋ฆฌ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๋„๋ฉ”์ธ์˜ ์‘์ง‘๋„๋ฅผ ๋†’์ผ ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ์‹œ) Product ์ƒ์„ฑ ๊ฐ€๋Šฅํ•œ์ง€ ํŒ๋‹จํ•˜๋Š” ์ฝ”๋“œ์™€ Product๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ๋ถ„๋ฆฌ ๋˜์–ด ์žˆ๋‹ค.

public class RegisterProductService {
    public ProductId registerNewProduct(NewProductRequest req) {
        Store account = accountRepository.findStoreById(req.getStoreId());
        
        checkNull(account);
        if(account.isBlocked()) {
            throw new StoreBlockedException();
        }
        ProductId id = productRepository.nextId();
        Product product = new Product(id, account.getId, ...);
        productRepository.save(product);
        return id;
    }
    ...
}

์œ„ ์ฝ”๋“œ๋Š” ์ค‘์š”ํ•œ ๋„๋ฉ”์ธ ๋กœ์ง ์ฒ˜๋ฆฌ๊ฐ€ ์‘์šฉ ์„œ๋น„์Šค์— ๋…ธ์ถœ๋˜์—ˆ๋‹ค. ์–ด๋–ป๊ฒŒ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์„๊นŒ?

Product์˜ ๊ฒฝ์šฐ ์ œํ’ˆ์„ ์ƒ์„ฑํ•œ Store์˜ ์‹๋ณ„์ž๋ฅผ ํ•„์š”๋กœ ํ•œ๋‹ค.

์ด ํžŒํŠธ๋กœ ๋ณด์•˜์„ ๋•Œ, ๋„๋ฉ”์ธ ๊ธฐ๋Šฅ์„ ๋„ฃ๊ธฐ ์œ„ํ•œ ๋ณ„๋„์˜ ๋„๋ฉ”์ธ ์„œ๋น„์Šค๋‚˜ ํŒฉํ† ๋ฆฌ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์ด ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ์— ๋” ์ข‹์€ ๊ณณ์€ Store ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ๋‹ค. ์ฆ‰. Store์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ด์šฉํ•ด์„œ Product๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— Store์— Product๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด Product๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ ์ผ๋ถ€๋ฅผ ์ง์ ‘ ์ œ๊ณตํ•˜๋ฉด์„œ ๋™์‹œ์— ์ค‘์š”ํ•œ ๋„๋ฉ”์ธ ๋กœ์ง์„ ํ•จ๊ป˜ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

public class Store extends Memeber {

    /* Product ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํŒฉํ† ๋ฆฌ ์—ญํ• ์„ ํ•œ๋‹ค. */
    public Product createProduct(ProductId newProductId, ...) {
        if(isBlocked()) {
            throw new StoreBlockedException();   
        }
        return new Product(newProductId, getId(), ...);
    }
}

โœ… ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ๊ฐ€ ๊ฐ–๊ณ  ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ด์šฉํ•ด์„œ ๋‹ค๋ฅธ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•œ๋‹ค๋ฉด, ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ์— ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•ด ๋ณผ ๊ฒƒ!

4. ๋ ˆํฌ์ง€ํ† ๋ฆฌ์™€ ๋ชจ๋ธ ๊ตฌํ˜„

  • ์—”ํ‹ฐํ‹ฐ์™€ ๋ฐธ๋ฅ˜ ๋งคํ•‘
  • ๋ฐธ๋ฅ˜ ์ปฌ๋ ‰์…˜ ๋งคํ•‘
  • ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ ๋กœ๋”ฉ ์ „๋žต๊ณผ ์˜์†์„ฑ ์ „ํŒŒ
  • ์‹๋ณ„์ž ์ƒ์„ฑ ๊ธฐ๋Šฅ

JPA ๋ฅผ ์ด์šฉํ•œ ๋ ˆํฌ์ง€ํ† ๋ฆฌ ๊ตฌํ˜„

์• ๊ทธ๋ฆฌ๊ฑฐํŠธ๋ฅผ ์–ด๋–ค ์ €์žฅ์†Œ์— ์ €์žฅํ•˜๋Š๋ƒ์— ๋”ฐ๋ผ ๋ ˆํฌ์ง€ํ„ฐ๋ฆฌ๋ฅด ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๋‹ค๋ฅด๋‹ค. ๋ ˆํฌ์ง€ํ† ๋ฆฌ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ์™€ ๊ฐ™์ด ๋„๋ฉ”์ธ ์˜์—ญ์— ์†ํ•˜๊ณ , ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋ฅผ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค๋Š” ์ธํ”„๋ผ ์ŠคํŠธ๋Ÿญ์ฒ˜ ์˜์—ญ ์— ์†ํ•œ๋‹ค.

Reference