Spring 의쑴 μ—­μ „ 원칙 (Dependency Inversion Principle)μ΄λž€?

2026. 1. 3. 15:40ㆍSpring

λ°˜μ‘ν˜•

 

 

 

 

DIP의 본질

  1. DIP μ›μΉ™μ΄λž€ κ°μ²΄μ—μ„œ μ–΄λ–€ Classλ₯Ό μ°Έμ‘°ν•΄μ„œ μ‚¬μš©ν•΄μ•Όν•˜λŠ” 상황이 생긴닀면, κ·Έ Classλ₯Ό 직접 μ°Έμ‘°ν•˜λŠ” 것이 μ•„λ‹ˆλΌ κ·Έ λŒ€μƒμ˜ μƒμœ„ μš”μ†Œ(좔상 클래슀 or μΈν„°νŽ˜μ΄μŠ€)둜 μ°Έμ‘°ν•˜λΌλŠ” 원칙이닀.
  2. DIPλ₯Ό λ‹¨μˆœνžˆ "μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ“°λ©΄ λœλ‹€"둜 μ΄ν•΄ν•˜λ©΄ μ‹€λ¬΄μ—μ„œ νŒ¨ν‚€μ§€ ꡬ쑰λ₯Ό 잘λͺ» μ„€κ³„ν•˜κ²Œ λœλ‹€.
    DDD의 λ ˆμ΄μ–΄ μ•„ν‚€ν…μ²˜μ™€ ν•¨κ»˜ μ˜μ‘΄μ„±μ˜ λ°©ν–₯을 μ œμ–΄ν•˜λŠ” μ›μΉ™μœΌλ‘œ 이해해야 ν•œλ‹€.
  3. 즉, 고차원 λͺ¨λ“ˆ(λΉ„μ¦ˆλ‹ˆμŠ€ 둜직)이 저차원 λͺ¨λ“ˆ(κ΅¬ν˜„ 세뢀사항)에 μ˜μ‘΄ν•˜λ©΄ μ•ˆλœλ‹€λŠ” 것이닀.
    1. μΈν„°νŽ˜μ΄μŠ€μ˜ μ†Œμœ κΆŒμ΄ μ€‘μš”ν•˜λ‹€. μΈν„°νŽ˜μ΄μŠ€λŠ” "μ‚¬μš©ν•˜λŠ” μͺ½"이 μ†Œμœ ν•œλ‹€
    2. μ˜μ‘΄μ„± λ°©ν–₯은 항상 μ•ˆμͺ½(도메인)을 ν–₯ν•œλ‹€
    3. κ΅¬ν˜„μ²΄κ°€ λ°”λ€Œμ–΄λ„ λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§μ€ 영ν–₯λ°›μ§€ μ•ŠλŠ”λ‹€
  4. μžμ‹ λ³΄λ‹€ λ³€ν•˜κΈ° μ‰¬μš΄ 것에 μ˜μ‘΄ν•˜λ˜ 것을 μΆ”μƒν™”λœ μΈν„°νŽ˜μ΄μŠ€λ‚˜ μƒμœ„ 클래슀λ₯Ό 두어 λ³€ν•˜κΈ° μ‰¬μš΄ κ²ƒμ˜ 변화에 영ν–₯λ°›μ§€ μ•Šκ²Œ ν•˜λŠ” 것이 의쑴 μ—­μ „ 원칙이닀.
 

 

“고차원 λͺ¨λ“ˆμ€ 저차원 λͺ¨λ“ˆμ— μ˜μ‘΄ν•˜λ©΄ μ•ˆ λœλ‹€. 이 두 λͺ¨λ“ˆ λͺ¨λ‘ λ‹€λ₯Έ μΆ”μƒν™”λœ 것에 μ˜μ‘΄ν•΄μ•Ό ν•œλ‹€.”
λ‘œλ²„νŠΈ C. λ§ˆν‹΄

  1. 고차원 λͺ¨λ“ˆ
    일반적으둜 더 큰 규λͺ¨μ˜ κΈ°λŠ₯을 μˆ˜ν–‰ν•˜λŠ” 클래슀, νŒ¨ν‚€μ§€ 등을 μ˜λ―Έν•œλ‹€.
    즉, μ‚¬μš©μž μΈν„°νŽ˜μ΄μŠ€μ™€ κ΄€λ ¨λœ μž‘μ—…μ„ ν•˜λŠ” Controllerλ‚˜ λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§μ„ μ²˜λ¦¬ν•˜λŠ” Service 계측이 고차원 λͺ¨λ“ˆμ— μ†ν•œλ‹€.
  2. 저차원 λͺ¨λ“ˆ
    고차원 λͺ¨λ“ˆμ—μ„œ μ •μ˜ν•œ κΈ°λŠ₯을 ꡬ체적으둜 κ΅¬ν˜„ν•˜λŠ” 클래슀 등을 μ˜λ―Έν•œλ‹€.
    주둜 λ°μ΄ν„°λ² μ΄μŠ€ μ ‘κ·Ό 객체(DAO) ν΄λž˜μŠ€λ‚˜ 파일 처리λ₯Ό μœ„ν•œ 클래슀 등이 저차원 λͺ¨λ“ˆμ— μ†ν•œλ‹€.

 

 

 

 

싀무 μ˜ˆμ‹œ: μ£Όλ¬Έ μ‹œμŠ€ν…œ

μ‹œλ‚˜λ¦¬μ˜€

μ£Όλ¬Έ 결제 λͺ¨λ“ˆμ„ ν˜„μž¬λŠ” ν† μŠ€νŽ˜μ΄λ¨ΌμΈ λ₯Ό μ“°μ§€λ§Œ, ν–₯ν›„ 카카였페이, λ„€μ΄λ²„νŽ˜μ΄λ‘œ ꡐ체될 수 μžˆλ‹€.

 

DIP μœ„λ°˜ ꡬ쑰

문제: μΈν„°νŽ˜μ΄μŠ€κ°€ infrastructure에 있으면, domain이 infrastructureλ₯Ό importν•΄μ•Ό 함을 κ°€μ •

com.example.shop
β”œβ”€β”€ domain
β”‚   └── order
β”‚       └── OrderService.java      // 도메인 μ„œλΉ„μŠ€
β”œβ”€β”€ infrastructure
β”‚   └── payment
β”‚       β”œβ”€β”€ PaymentGateway.java    // μΈν„°νŽ˜μ΄μŠ€ ← 문제!
β”‚       └── TossPaymentGateway.java
...  


// OrderService.java
// → κ³ μˆ˜μ€€(domain)이 μ €μˆ˜μ€€(infrastructure)에 의쑴
import com.example.shop.infrastructure.payment.PaymentGateway; // ❌ μœ„λ°˜!
 
 

DIP μ€€μˆ˜ ꡬ쑰

com.example.shop
β”œβ”€β”€ domain
β”‚   └── order
β”‚       β”œβ”€β”€ Order.java                    // μ—”ν‹°ν‹°
β”‚       β”œβ”€β”€ OrderService.java             // 도메인 μ„œλΉ„μŠ€
β”‚       └── PaymentProcessor.java         // μΈν„°νŽ˜μ΄μŠ€ ← 도메인이 μ†Œμœ ν•΄μ•Όν•¨!
β”‚
β”œβ”€β”€ infrastructure
β”‚   └── payment
β”‚       └── TossPaymentProcessor.java     // κ΅¬ν˜„μ²΄
β”‚
└── application
    └── order
        └── OrderFacade.java              // 쑰립(DI μ„€μ •)

 

 

 

 

 

 

 

 

 

 

 

 

DIPκ°€ DDDμ—μ„œ μž‘λ™ν•˜λŠ” 방식

μ•„ν‚€ν…μ²˜ 레벨둜 μ΄ν•΄ν•˜κΈ°

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚           Presentation                 β”‚  ← Controller, DTO
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚           Application                  β”‚  ← UseCase, Facade
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚             Domain                     β”‚  ← Entity, Value Object, Domain Service
β”‚                                        β”‚     Repository Interface ← μ—¬κΈ° μ •μ˜!
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚          Infrastructure                β”‚  ← Repository κ΅¬ν˜„, μ™ΈλΆ€ API 연동
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
의쑴 λ°©ν–₯: λ°”κΉ₯ → μ•ˆμͺ½ (ν•œ λ°©ν–₯만 ν—ˆμš©)​

 

 

 

의쑴 λ°©ν–₯으둜 μ΄ν•΄ν•˜κΈ°

Infrastructureκ°€ Domain을 μ˜μ‘΄ν•˜λ©°, Domain은 Infrastructure λͺ°λΌλ„ λœλ‹€.

 

               의쑴 λ°©ν–₯ (컴파일 νƒ€μž„)
─────────────────────────────────▢
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚Presentation│──▢│Application │──▢│   Domain   │◀──│Infrastructureβ”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

 

 

 

λ³€κ²½ λΉˆλ„λ‘œ μ΄ν•΄ν•˜κΈ°

κ°€μž₯ μ•ˆμ •μ μΈ Domain을 μ€‘μ‹¬μœΌλ‘œ 자주 λ³€κ²½λ˜λŠ” 것듀이 Domain에 μ˜μ‘΄ν•˜λ©° Domain은 μ™ΈλΆ€ 변경에 영ν–₯λ°›μ§€ μ•ŠλŠ”λ‹€.

계측 λ³€κ²½ λΉˆλ„ μ˜ˆμ‹œ
Infrastructure 자주 λ³€κ²½ DB ꡐ체, API 버전업 
Presentation 자주 λ³€κ²½ UI 개편, API μŠ€νŽ™
Application 가끔 λ³€κ²½ μœ μŠ€μΌ€μ΄μŠ€ μΆ”κ°€
Domain 거의 μ•ˆ 변함 핡심 λΉ„μ¦ˆλ‹ˆμŠ€ κ·œμΉ™ μΆ”κ°€

 

 

μ™œ μ΄λ ‡κ²Œ ν•˜λŠ”κ°€?

관점 DIP 미적용 DIP 적용
κ²°μ œμ‚¬ ꡐ체 μ‹œ OrderService μ½”λ“œ μˆ˜μ • ν•„μš” κ΅¬ν˜„μ²΄λ§Œ ꡐ체, μ„€μ • λ³€κ²½
λ‹¨μœ„ ν…ŒμŠ€νŠΈ μ‹€μ œ 결제 API 호좜됨 Mock μ£Όμž…μœΌλ‘œ λΉ λ₯Έ ν…ŒμŠ€νŠΈ
도메인 μˆœμˆ˜μ„± μ™ΈλΆ€ λΌμ΄λΈŒλŸ¬λ¦¬μ— μ˜€μ—Ό λΉ„μ¦ˆλ‹ˆμŠ€ 둜직만 쑴재
컴파일 μ˜μ‘΄μ„± infrastructure λ³€κ²½ μ‹œ domain 재컴파일 domain은 영ν–₯ μ—†μŒ

 

 

λ°˜μ‘ν˜•