nika-blog

๐Ÿ— ๋„๋ฉ”์ธ ์ฃผ๋„ ์„ค๊ณ„(DDD) - ํŒŒํŠธ2 ๋ชจ๋ธ ์ฃผ๋„ ์„ค๊ณ„์˜ ๋นŒ๋”ฉ ๋ธ”๋ก ๋ณธ๋ฌธ

์นดํ…Œ๊ณ ๋ฆฌ ์—†์Œ

๐Ÿ— ๋„๋ฉ”์ธ ์ฃผ๋„ ์„ค๊ณ„(DDD) - ํŒŒํŠธ2 ๋ชจ๋ธ ์ฃผ๋„ ์„ค๊ณ„์˜ ๋นŒ๋”ฉ ๋ธ”๋ก

nika0 2025. 2. 23. 14:13

๐Ÿš€ ๊ฐ์ฒด์ง€ํ–ฅ ์„ค๊ณ„์—์„œ ๋„๋ฉ”์ธ ์ฃผ๋„ ์„ค๊ณ„๋กœ

๐Ÿ“Œ ๊ฐ์ฒด์ง€ํ–ฅ ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ DDD ์ฒ ํ•™์ด ๋“ฑ์žฅ

  • ๊ฐ์ฒด ๋ชจ๋ธ๋ง์„ ์‹ค๋ฌด ์†Œํ”„ํŠธ์›จ์–ด ํ”„๋กœ์ ํŠธ์— ์–ด๋–ป๊ฒŒ ์ ์šฉํ•  ๊ฒƒ์ธ์ง€์— ๋Œ€ํ•œ ๋…ผ์˜
  • ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ๊ณผ DDD๊ฐ€ ํ•จ๊ป˜ ๋ฐœ์ „

๐Ÿ•ฐ 1990~2000๋…„๋Œ€: OOP์™€ DDD์˜ ๋“ฑ์žฅ ๋ฐฐ๊ฒฝ

๐Ÿ”น 1) ๊ฐ์ฒด ์ง€ํ–ฅ์ด ์œ ํ–‰ํ•˜๊ธฐ ์‹œ์ž‘ํ•œ ์ด์œ ?

  • GUI(Graphical User Interface)์˜ ๋“ฑ์žฅ
    • ๊ฐ์ฒด์ง€ํ–ฅ์€ UI์™€ ์ž˜ ๋งž๋Š” ํŒจ๋Ÿฌ๋‹ค์ž„
    • ์ด๋ฒคํŠธ(๋ฉ”์‹œ์ง€) → ํŠน์ • UI(๊ฐ์ฒด) ๋ณ€๊ฒฝ
  • ์ฆ‰, OOP๋Š” ํด๋ผ์ด์–ธํŠธ ๊ฐœ๋ฐœ์— ์ ํ•ฉํ•œ ํŒจ๋Ÿฌ๋‹ค์ž„

๐Ÿ”น 2) CS(Computer Science) ๋ถ„์•ผ์˜ ๋ณ€ํ™”

  • ์›น(Web) ๊ฐœ๋ฐœ์˜ ๋Œ€๋‘
    • ์ด์ „๊นŒ์ง€๋Š” ๋กœ์ปฌ ์ปดํ“จํ„ฐ ๋‚ด์—์„œ ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ฌ์šฉ
    • ์›น์ด ๋“ฑ์žฅํ•˜๋ฉด์„œ ๋„คํŠธ์›Œํฌ, ๋ถ„์‚ฐ ์‹œ์Šคํ…œ ๊ด€๋ จ ๊ธฐ์ˆ ์ด ํ•„์ˆ˜ ์š”์†Œ๋กœ ๋ณ€ํ™”
  • ๋ถ„์‚ฐ ๊ฐ์ฒด ๊ธฐ์ˆ ์˜ ์œ ํ–‰
    • ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด ๋‹ค๋ฅธ ์‹œ์Šคํ…œ์˜ ๊ฐ์ฒด๋„ ๊ฐ™์€ ๋ฉ”๋ชจ๋ฆฌ์— ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋™์ž‘
    • ํ•˜์ง€๋งŒ ๊ธฐ์ˆ ๊ณผ ๋„๋ฉ”์ธ์ด ํ˜ผ์žฌ๋˜๋Š” ๋ฌธ์ œ ๋ฐœ์ƒ
    • ๊ธฐ์ˆ ์ด ๋„๋ฉ”์ธ์„ ์นจํˆฌ(Pervasive)ํ•˜๋Š” ๊ตฌ์กฐ
      • ์„œ๋ฒ„๊ฐ€ ๊บผ์ ธ ์žˆ์œผ๋ฉด ์ฝ”๋“œ ์‹คํ–‰์ด ๋ถˆ๊ฐ€๋Šฅ
      • ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊ณผ ์ธํ”„๋ผ ์ฝ”๋“œ๊ฐ€ ๊ฒฐํ•ฉ๋จ
      • ์˜์†์„ฑ ๊ฐ์ฒด(Persistence Object) ๊ตฌํ˜„ ํ•„์š”
      • ๊ฒฐ๋ก : ๊ฐ์ฒด ๋‹จ์œ„๋กœ ๋ถ„์‚ฐํ•  ํ•„์š” ์—†์ด, ์„œ๋น„์Šค ๋‹จ์œ„๋กœ๋งŒ ๋ถ„์‚ฐํ•˜๋ฉด ์ถฉ๋ถ„!
  • Spring ๋“ฑ์žฅ๊ณผ POJO(Plain Old Java Object) ๊ฐœ๋… ํ™•์‚ฐ
    • ๊ธฐ์ˆ  ์ข…์†์ ์ธ ์ฝ”๋“œ ์ž‘์„ฑ ๋ฐฉ์‹์—์„œ ๋ฒ—์–ด๋‚˜๋ ค๋Š” ์‹œ๋„
    • "๋„๋ฉ”์ธ์ด ๊ธฐ์ˆ ์„ ์ฃผ๋„ํ•ด์•ผ ํ•œ๋‹ค"๋ผ๋Š” ์ฒ ํ•™์ด ๋“ฑ์žฅ
    • DDD(๋„๋ฉ”์ธ ์ฃผ๋„ ์„ค๊ณ„)๊ฐ€ ํƒ„์ƒ๋ชจ๋ธ์„ ์ค‘์‹ฌ์œผ๋กœ ์ฝ”๋“œ ์ž‘์„ฑ

๐Ÿ”น 3) ํ˜„์žฌ: ๋„๋ฉ”์ธ ์ค‘์‹ฌ ๊ฐœ๋ฐœ์ด ๋‹น์—ฐํ•œ ์‹œ๋Œ€

  • ๋„๋ฉ”์ธ ์ฃผ๋„ ์„ค๊ณ„ ๊ฐœ๋…์ด ๋„๋ฆฌ ๋ฐ›์•„๋“ค์—ฌ์ง
  • ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค, ํด๋ฆฐ ์•„ํ‚คํ…์ฒ˜ ๋“ฑ๊ณผ ๊ฒฐํ•ฉ๋˜๋ฉด์„œ ๋”์šฑ ๋ฐœ์ „

๐Ÿ— ๋„๋ฉ”์ธ ๋กœ์ง์˜ ๊ฒฉ๋ฆฌ

๐Ÿ’ก ๊ธฐ์ˆ ์ ์ธ ์š”์†Œ๋ฅผ ๋„๋ฉ”์ธ ๋กœ์ง์—์„œ ๋ถ„๋ฆฌํ•˜๊ณ  ์‹ถ๋‹ค!

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋Œ€ํ‘œ์ ์ธ ๋ฐฉ๋ฒ•: ๋ ˆ์ด์–ด ์•„ํ‚คํ…์ฒ˜
(ํ•˜์ง€๋งŒ DDD๋ฅผ ํ•œ๋‹ค๊ณ  ๋ฐ˜๋“œ์‹œ ๋ ˆ์ด์–ด ์•„ํ‚คํ…์ฒ˜๋ฅผ ์จ์•ผ ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹˜)

๐Ÿ”น ๋ ˆ์ด์–ด ์•„ํ‚คํ…์ฒ˜ (Layered Architecture)

1๏ธโƒฃ User Interface (UI)

  • ์‚ฌ์šฉ์ž๊ฐ€ ์‹œ์Šคํ…œ๊ณผ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ๊ณ„์ธต
    2๏ธโƒฃ Application
  • ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์‹คํ–‰ํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋น„์Šค ๊ณ„์ธต
    3๏ธโƒฃ Domain
  • ํ•ต์‹ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ํฌํ•จ๋œ ๊ณ„์ธต (DDD์˜ ์ค‘์‹ฌ)
    4๏ธโƒฃ Infrastructure
  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค, ์™ธ๋ถ€ API, ๋ฉ”์‹œ์ง€ ํ ๋“ฑ๊ณผ ์—ฐ๊ฒฐ

โœ… ์ด ๊ตฌ์กฐ๋ฅผ ํ†ตํ•ด ๊ธฐ์ˆ ์ ์ธ ์š”์†Œ์™€ ๋„๋ฉ”์ธ ๋กœ์ง์„ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์Œ!


๐Ÿ”จ ๋ชจ๋ธ ์ฃผ๋„ ์„ค๊ณ„์˜ ๋นŒ๋”ฉ ๋ธ”๋ก (Building Blocks)

DDD๋Š” ์ฝ”๋“œ ๋ณต์žก์„ฑ์„ ์ค„์ด๊ธฐ ์œ„ํ•ด ๋„๋ฉ”์ธ์„ ํŠน์ • ์—ญํ• ๋ณ„๋กœ ๋ถ„๋ฅ˜ํ•ฉ๋‹ˆ๋‹ค.
์ด๋ฅผ ์œ„ํ•ด ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋นŒ๋”ฉ ๋ธ”๋ก์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐ŸŽฏ 1) ๋„๋ฉ”์ธ์„ ํ‘œํ˜„ํ•˜๋Š” ๋นŒ๋”ฉ ๋ธ”๋ก

์ด๋“ค์€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ฝ”๋“œ๋กœ ํ‘œํ˜„ํ•˜๋Š” ํ•ต์‹ฌ ์š”์†Œ์ž…๋‹ˆ๋‹ค.

๋นŒ๋”ฉ ๋ธ”๋ก์„ค๋ช…

Association (์—ฐ๊ด€ ๊ด€๊ณ„) ๊ฐ์ฒด ๊ฐ„์˜ ๊ด€๊ณ„ ํ‘œํ˜„
Value Object (๊ฐ’ ๊ฐ์ฒด) ๋ถˆ๋ณ€์ด๋ฉฐ ๋™์ผ์„ฑ๋ณด๋‹ค ๊ฐ’์ด ์ค‘์š”ํ•œ ๊ฐ์ฒด
Entity (์—”ํ‹ฐํ‹ฐ) ๊ณ ์œ ํ•œ ์‹๋ณ„์ž๋ฅผ ๊ฐ€์ง€๋Š” ๊ฐ์ฒด
Service (์„œ๋น„์Šค) ํŠน์ • ์—”ํ‹ฐํ‹ฐ์— ์†ํ•˜์ง€ ์•Š๋Š” ๋„๋ฉ”์ธ ๋กœ์ง ์ฒ˜๋ฆฌ
Module (๋ชจ๋“ˆ) ๊ด€๋ จ๋œ ๋„๋ฉ”์ธ ๊ฐœ๋…์„ ๋…ผ๋ฆฌ์ ์œผ๋กœ ๋ฌถ์Œ

๐ŸŽฏ 2) ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋นŒ๋”ฉ ๋ธ”๋ก

์ด๋“ค์€ ๊ฐ์ฒด์˜ ์ƒ์„ฑ๊ณผ ์ €์žฅ์„ ๋‹ค๋ฃจ๋Š” ์š”์†Œ์ž…๋‹ˆ๋‹ค.

๋นŒ๋”ฉ ๋ธ”๋ก์„ค๋ช…

Aggregate (์• ๊ทธ๋ฆฌ๊ฒŒ์ดํŠธ) ๋ถˆ๋ณ€์‹์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ์ฒด ๊ทธ๋ฃน
Repository (๋ฆฌํฌ์ง€ํ† ๋ฆฌ) ์• ๊ทธ๋ฆฌ๊ฒŒ์ดํŠธ๋ฅผ ์ €์žฅํ•˜๊ณ  ์กฐํšŒํ•˜๋Š” ์—ญํ• 
Factory (ํŒฉํ† ๋ฆฌ) ๋ณต์žกํ•œ ๊ฐ์ฒด ์ƒ์„ฑ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์—ญํ• 

โœ… ์ด๋Ÿฌํ•œ ๋นŒ๋”ฉ ๋ธ”๋ก์„ ํ™œ์šฉํ•˜๋ฉด ์ฝ”๋“œ์˜ ์‘์ง‘๋„๋ฅผ ๋†’์ด๊ณ  ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถœ ์ˆ˜ ์žˆ์Œ!


๐Ÿ“Œ ๋„๋ฉ”์ธ ๋ชจ๋ธ ์˜ˆ์ œ - ๋ถˆ๋ณ€์‹(Invariant) ๊ด€๋ฆฌ

๋„๋ฉ”์ธ ๋กœ์ง์„ ์„ค๊ณ„ํ•  ๋•Œ **๋ถˆ๋ณ€์‹(Invariant)**์„ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ’ก ๋ถˆ๋ณ€์‹์ด๋ž€?

  • ์‹œ์Šคํ…œ์—์„œ ๋ฐ˜๋“œ์‹œ ์œ ์ง€๋˜์–ด์•ผ ํ•˜๋Š” ๊ทœ์น™
  • ์˜ˆ์ œ:
    • Order(์ฃผ๋ฌธ)์˜ ์ด ๊ธˆ์•ก์€ LimitPrice(์ตœ๋Œ€ ๊ฐ€๊ฒฉ)๋ณด๋‹ค ์ž‘์•„์•ผ ํ•œ๋‹ค.

โŒ ๋ถˆ๋ณ€์‹์„ ๊นจ๋œจ๋ฆฌ๋Š” ๋ฌธ์ œ (๋™์‹œ์„ฑ ์ด์Šˆ)

  • User1์ด Order ๊ฐ์ฒด๋ฅผ ์ˆ˜์ •
  • User2๋„ ๊ฐ™์€ Order ๊ฐ์ฒด๋ฅผ ์ˆ˜์ •
  • DB ์—…๋ฐ์ดํŠธ ์‹œ ๋ณ€๊ฒฝ๋œ ๊ฒƒ๋งŒ ์ €์žฅํ•œ๋‹ค๋ฉด?
    • → ๋ถˆ๋ณ€์‹ ์œ„๋ฐ˜ ๊ฐ€๋Šฅ์„ฑ ๋ฐœ์ƒ

โœ… ํ•ด๊ฒฐ์ฑ…: Aggregate(์• ๊ทธ๋ฆฌ๊ฒŒ์ดํŠธ) ์‚ฌ์šฉ

  • ๋ถˆ๋ณ€์‹์„ ๋งŒ์กฑํ•˜๋Š” ๊ฐ์ฒด ๊ทธ๋ฃน ๋‹จ์œ„๋กœ ์ฒ˜๋ฆฌ
  • Aggregate ๋‚ด๋ถ€์—์„œ ๋ณ€๊ฒฝ, DB ์—…๋ฐ์ดํŠธ ๋“ฑ ๋ชจ๋“  ์ž‘์—…์„ ํŠธ๋žœ์žญ์…˜ ๋‹จ์œ„๋กœ ์ฒ˜๋ฆฌ
  • ์ฆ‰, ๋„๋ฉ”์ธ ๋ฃฐ(๋น„์ฆˆ๋‹ˆ์Šค ๋ฃฐ)์— ๋”ฐ๋ผ ํ•œ๊บผ๋ฒˆ์— ์—…๋ฐ์ดํŠธ

โœ… ๊ฒฐ๊ณผ์ ์œผ๋กœ, ์• ๊ทธ๋ฆฌ๊ฒŒ์ดํŠธ๋Š” ๋ฐ์ดํ„ฐ ์ •ํ•ฉ์„ฑ์„ ๋ณด์žฅํ•˜๋Š” ์—ญํ• ์„ ์ˆ˜ํ–‰


๐Ÿ”„ ๊ฒฐ๊ณผ์  ์ผ๊ด€์„ฑ (Eventual Consistency)

  • ์˜ˆ์ œ: ์ฃผ๋ฌธ ์ˆ˜(Order Count) ์—…๋ฐ์ดํŠธ
    • ์ฃผ๋ฌธ์„ ์ƒ์„ฑํ•  ๋•Œ, ์ฃผ๋ฌธ ๊ฐœ์ˆ˜๋ฅผ ๋ณ„๋„์˜ ํŠธ๋žœ์žญ์…˜์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒฝ์šฐ
    • ์ฆ‰, ์ฃผ๋ฌธ ๊ฐœ์ˆ˜ ์—…๋ฐ์ดํŠธ๊ฐ€ ์ฃผ๋ฌธ ์ƒ์„ฑ ํŠธ๋žœ์žญ์…˜๊ณผ ๋ณ„๋„๋กœ ์‹คํ–‰๋จ
  • ๋ชจ๋“  ํŠธ๋žœ์žญ์…˜์ด ์ฆ‰์‹œ ๋ฐ˜์˜๋˜์ง€ ์•Š์•„๋„ ๊ดœ์ฐฎ์Œ → ๊ฒฐ๊ณผ์ ์œผ๋กœ ์ผ๊ด€์„ฑ์ด ์œ ์ง€๋˜๋ฉด ๋จ
  • ์ด๋Ÿฐ ๋ฐฉ์‹์€ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ์•„ํ‚คํ…์ฒ˜์—์„œ ๋งŽ์ด ์‚ฌ์šฉ๋จ

๐Ÿ† ๋งˆ๋ฌด๋ฆฌ: DDD๋ฅผ ์ ์šฉํ•˜๋ฉด?

โœ… ๊ธฐ์ˆ ์ด ๋„๋ฉ”์ธ์„ ์ง€๋ฐฐํ•˜์ง€ ์•Š๊ณ , ๋„๋ฉ”์ธ์ด ๊ธฐ์ˆ ์„ ์ฃผ๋„ํ•˜๋Š” ์„ค๊ณ„
โœ… ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ฝ”๋“œ์™€ ๋™์ผํ•˜๊ฒŒ ์œ ์ง€ (๋ชจ๋ธ = ์ฝ”๋“œ)
โœ… ๋ ˆ์ด์–ด ์•„ํ‚คํ…์ฒ˜์™€ ๋นŒ๋”ฉ ๋ธ”๋ก์„ ํ™œ์šฉํ•˜์—ฌ ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ๋†’์ž„
โœ… ๋ถˆ๋ณ€์‹์„ ์ง€ํ‚ค๋ฉฐ ๋ฐ์ดํ„ฐ ์ •ํ•ฉ์„ฑ์„ ๋ณด์žฅ

DDD๋Š” ๋‹จ์ˆœํ•œ ๊ฐœ๋ฐœ ๋ฐฉ๋ฒ•๋ก ์ด ์•„๋‹ˆ๋ผ ๋น„์ฆˆ๋‹ˆ์Šค ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ์ฒ ํ•™์ž…๋‹ˆ๋‹ค.
๊ธฐ์ˆ ์ด ์•„๋‹Œ ๋„๋ฉ”์ธ ์ค‘์‹ฌ์˜ ์‚ฌ๊ณ ๋ฐฉ์‹์œผ๋กœ ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์ด ํ•ต์‹ฌ! ๐Ÿš€