λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

μ•„ν‚€ν…μ²˜

πŸ—οΈ μ•„ν‚€ν…μ²˜ 섀계 - 무엇이 무엇을 μ–΄λ””κΉŒμ§€ μ˜μ‘΄ν•΄μ•Ό ν• κΉŒ?

μ™œ 이 글을 μ“°κ²Œ λ˜μ—ˆμ„κΉŒ?

κ°œλ°œμ„ 처음 배울 땐 컨트둀러, μ„œλΉ„μŠ€, 리포지토리. λ”± μ„Έ 개의 λ ˆμ΄μ–΄λ‘œ ν”„λ‘œμ νŠΈλ₯Ό λ‚˜λˆ΄λ‹€. 그리고 λŒ€λΆ€λΆ„μ˜ λ‘œμ§μ€ μ„œλΉ„μŠ€μ— λͺ°μ•„λ„£μ—ˆλ‹€. κ·Έλ•ŒλŠ” κ·Έκ²ƒλ§ŒμœΌλ‘œλ„ μ–΄λŠ μ •λ„λŠ” 역할이 뢄리 λœλ‹€κ³  μƒκ°ν–ˆλ‹€.

 

그런데 μ‹œκ°„μ΄ μ§€λ‚˜κ³  κ°œλ°œμ„ μ‘°κΈˆμ”© 더 ν•˜λ‹€ λ³΄λ‹ˆ, ‘μ„œλΉ„μŠ€μ— λ‘œμ§μ„ λ„£λŠ”λ‹€’λŠ” 말 μžμ²΄κ°€ 점점 λͺ¨ν˜Έν•˜κ²Œ λŠκ»΄μ‘Œλ‹€. ‘μ„œλΉ„μŠ€’λΌλŠ”κ²Œ 무엇인지, ‘λΉ„μ¦ˆλ‹ˆμŠ€ 둜직’은 μ–΄λ””κΉŒμ§€κ³ , ‘도메인 둜직’은 μ–΄λ””κΉŒμ§€μΈμ§€ 고민이 λ˜μ—ˆλ‹€.

 

이런 고민이 κΉŠμ–΄μ§ˆ 즈음, νšŒμ‚¬μ—μ„œ ν”„λ‘ νŠΈμ—”λ“œ 업무도 같이 ν•˜κ²Œ 됐닀. ν”„λ‘ νŠΈμ—”λ“œλŠ” λ°±μ—”λ“œλ³΄λ‹€ 훨씬 μ–•κ²Œ μ•Œκ³  μžˆμ§€λ§Œ, ν”„λ‘ νŠΈ μ—­μ‹œμ„€κ³„μ—μ„œ ‘μ˜μ‘΄μ„±’은 ꡉμž₯히 μ€‘μš”ν•œ λ¬Έμ œλΌλŠ” 것을 λŠκΌˆλ‹€.

 

μ˜μ‘΄μ„±μ΄ ν•œ 번 꼬이기 μ‹œμž‘ν•˜λ©΄ μœ μ§€λ³΄μˆ˜μ™€ κΈ°λŠ₯ 변경이 ꡉμž₯히 νž˜λ“€μ–΄μ§„λ‹€. κ·Έλž˜μ„œ 이번 κΈ€μ—μ„œλŠ” μ˜μ‘΄μ„± 섀계가 μ™œ μ€‘μš”ν•œμ§€, 그것에 λŒ€ν•œ μ–΄λ–€ 결둠을 λ‚΄λ ΈλŠ”μ§€μ— 생각을 정리해보렀 ν•œλ‹€.


μ˜μ‘΄μ„±μ΄ 꼬이면 μƒκΈ°λŠ” 일듀

μ˜μ‘΄μ„± 섀계가 잘λͺ»λ˜λ©΄ μ–΄λ–€ λ¬Έμ œκ°€ μƒκΈΈκΉŒ? λ„ˆλ¬΄ κ±°μ°½ν•˜κ²Œ ‘μ•„ν‚€ν…μ²˜’λΌλŠ” 단어λ₯Ό 쓰지 μ•Šλ”λΌλ„, λͺ‡ 가지 μƒν™©λ§Œ λ– μ˜¬λ €λ³΄λ©΄ 감이 올 수 μžˆλ‹€.

 

  • A κΈ°λŠ₯을 λ°”κΎΈλ €κ³  ν–ˆλŠ”λ°, μ „ν˜€ κ΄€λ ¨ μ—†μ–΄ λ³΄μ΄λŠ” B, C κΈ°λŠ₯도 같이 κΉ¨μ‘Œλ‹€.
  • μƒˆλ‘œμš΄ κΈ°λŠ₯을 λ„£μœΌλ €κ³  ν–ˆλ”λ‹ˆ μ–΄λ””λΆ€ν„° λ„£μ–΄μ•Ό 할지 감이 μ•ˆ μ˜¨λ‹€.
  • ν…ŒμŠ€νŠΈ μ½”λ“œ μ§œλŠ” 게 μ–΄λ ΅λ‹€. μ–΄λ–€ ν΄λž˜μŠ€μ— μ–΄λ–€ μ±…μž„μ΄ μžˆλŠ”μ§€ λͺ¨λ₯΄κ² λ‹€.
  • νŠΉμ • κ΅¬ν˜„μ²΄λ₯Ό λ°”κΎΈκ³  싢은데, μƒμœ„ 둜직이 κ·Έ κ΅¬ν˜„μ²΄μ— 직접 μ˜μ‘΄ν•˜κ³  μžˆμ–΄μ„œ λ°”κΎΈλŠ” 데 λ„ˆλ¬΄ λ§Žμ€ λ¦¬μŠ€ν¬κ°€ λ”°λ₯Έλ‹€.

이런 λ¬Έμ œλ“€μ€ λŒ€λΆ€λΆ„ μ˜μ‘΄μ„±μ˜ λ°©ν–₯이 잘λͺ»λ˜μ—ˆκ±°λ‚˜, 관심사가 λ’€μ„žμ—¬ μžˆμ„ λ•Œ λ°œμƒν•œλ‹€.

 

κ·Έλž˜μ„œ μ„€κ³„μ—μ„œ κ°€μž₯ λ¨Όμ € κ³ λ €ν•΄μ•Ό ν•  건 λ ˆμ΄μ–΄λ₯Ό λ‚˜λˆ„λŠ” 기쀀보닀도 무엇이 무엇에 μ˜μ‘΄ν•΄μ•Ό ν•˜κ³ , 무엇은 μ ˆλŒ€ μ˜μ‘΄ν•˜μ§€ 말아야 ν•˜λŠ”μ§€μ— λŒ€ν•œ 생각이라고 λŠκΌˆλ‹€.


λ‚΄κ°€ μƒκ°ν•œ μ˜μ‘΄μ„±μ˜ λ°©ν–₯

μ΄λ²ˆμ— 개인적으둜 생각해 λ³Έ ꡬ성은 λ‹€μŒκ³Ό κ°™λ‹€. ν”νžˆ λ§ν•˜λŠ” 3-tier ꡬ쑰(Controller, Service, Repository)μ—μ„œ ‘Service’λΌλŠ” 이름 μ•„λž˜ λ­‰λš±κ·Έλ €μ‘Œλ˜ 뢀뢄을 μ’€ 더 μ—­ν• λ³„λ‘œ λΆ„λ¦¬ν•˜λŠ” λ°©ν–₯이닀.

μ˜μ‘΄μ„± 뢄리 κΈ°μ€€

1. Application Layer (μ΅œμƒμœ„ 둜직 μ‘°ν•©)

  • μ—¬λŸ¬ 도메인 λ‘œμ§μ„ μ‘°ν•©ν•˜κ±°λ‚˜, μ™ΈλΆ€ μš”μ²­ 흐름을 관리
  • ν”„λ ˆμ  ν…Œμ΄μ…˜ κ³„μΈ΅μ΄λ‚˜ μ™ΈλΆ€ 호좜과 κ°€μž₯ κ°€κΉŒμ›€
  • Controller, Scheduler 등이 ν˜ΈμΆœν•˜λŠ” μ£Όμš” μ§„μž…μ 

2. Domain Layer (핡심 λΉ„μ¦ˆλ‹ˆμŠ€ 둜직)

  • μ‹€μ œ 도메인 λ‘œμ§μ„ λ‹΄λ‹Ήν•˜λŠ” μ˜μ—­
  • 객체 κ°„ ν˜‘λ ₯, μ •μ±… νŒλ‹¨, 핡심 도메인 ν–‰μœ„ κ΅¬ν˜„

3. Infrastructure Layer (μ™ΈλΆ€ 의쑴 μΊ‘μŠν™”)

  • μ™ΈλΆ€ API 호좜, DB 연동, λ©”μ‹œμ§• λ“±
  • 도메인 λ‘œμ§μ— 직접 영ν–₯ 주지 μ•Šλ„λ‘ μΈν„°νŽ˜μ΄μŠ€λ‘œ 뢄리

4. Support Layer (보쑰 κΈ°λŠ₯ 제곡)

  • μœ ν‹Έμ„± κΈ°λŠ₯ (λ‚ μ§œ 포맷 λ³€ν™˜, λ¬Έμžμ—΄ 계산 λ“±)
  • λͺ¨λ“  λ ˆμ΄μ–΄μ—μ„œ κ³΅ν†΅μ μœΌλ‘œ 의쑴 κ°€λŠ₯

μ˜μ‘΄μ„± 흐름도

                   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                   β”‚   Application Layer    β”‚
                   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                               β”‚
          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
          ↓                    ↓                        ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Domain Layer  β”‚ β”‚Infrastructure Layer β”‚ β”‚   Support Layer   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
         β”‚                      β”‚                       β–²
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  • Application LayerλŠ” Domain, Infra, Support λͺ¨λ‘λ₯Ό 의쑴 κ°€λŠ₯
  • Domain LayerλŠ” Support만 의쑴 κ°€λŠ₯
  • Infrastructure Layer도 Support만 의쑴 κ°€λŠ₯

이런 ꡬ쑰λ₯Ό λ”°λ₯΄κ²Œ 되면 μžμ—°μŠ€λŸ½κ²Œ 도메인 λ‘œμ§μ€ μ™ΈλΆ€ κ΅¬ν˜„μ²΄μ— 영ν–₯을 받지 μ•Šκ³ , InfraλŠ” Interfaceλ₯Ό 톡해 ꡐ체 κ°€λŠ₯ν•˜λ©°, Application은 전체 흐름을 μ‘°μœ¨ν•˜λŠ” 역할에 집쀑할 수 μžˆλ‹€κ³  μƒκ°ν•œλ‹€.


νŒ¨ν‚€μ§€ ꡬ쑰 μ˜ˆμ‹œ

com.myproject
β”œβ”€β”€ application
β”‚   └── OrderUseCase.kt
β”œβ”€β”€ domain
β”‚   β”œβ”€β”€ model
β”‚   β”‚   └── Order.kt
β”‚   └── service
β”‚       └── OrderDomainService.kt
β”œβ”€β”€ infrastructure
β”‚   β”œβ”€β”€ persistence
β”‚   β”‚   └── OrderRepositoryImpl.kt
β”‚   └── external
β”‚       └── ExternalPaymentClient.kt
β”œβ”€β”€ support
β”‚   └── DateUtils.kt
└── presentation
    └── OrderController.kt

μ™œ μ΄λ ‡κ²Œ λ‚˜λˆ΄μ„κΉŒ?

도메인과 인프라가 μ„žμ—¬ μžˆλŠ” κ΅¬μ‘°μ—μ„œλŠ” λ‹€μŒκ³Ό 같은 λ¬Έμ œλ“€μ΄ λ°˜λ³΅λλ‹€.

  • μ™ΈλΆ€ API ν˜•μ‹μ΄ λ°”λ€Œλ©΄ 도메인 λ‘œμ§λ„ 같이 λ°”λ€Œμ—ˆλ‹€.
  • λ‚ μ§œ κ³„μ‚°μ²˜λŸΌ λ‹¨μˆœν•œ 둜직이 μ—¬κΈ°μ €κΈ° μ€‘λ³΅λ˜μ–΄ μžˆμ—ˆλ‹€.
  • 도메인 λ‘œμ§μ— λ©”μ‹œμ§€ νλ‚˜ μ™ΈλΆ€ 라이브러리 둜직이 μ„žμ—¬ μžˆμ–΄ ν…ŒμŠ€νŠΈκ°€ λΆˆνŽΈν–ˆλ‹€.

반면 μœ„ ꡬ쑰처럼 λ‚˜λˆ„λ©΄ μ•„λž˜μ™€ 같은 μž₯점이 μžˆλ‹€.

  • 도메인 μ˜μ—­μ€ μˆœμˆ˜ν•˜κ²Œ 남기 λ•Œλ¬Έμ—, ν…ŒμŠ€νŠΈ μž‘μ„±μ΄ μ‰¬μ›Œμ§€κ³  변경에 μœ μ—°ν•˜λ‹€.
  • μ™ΈλΆ€ API μš”μ²­μ„ μΊ‘μŠν™”ν•œ μ˜μ—­μ€ mocking ν•˜κΈ°λ„ νŽΈν•˜λ‹€.
  • λΉ„μ¦ˆλ‹ˆμŠ€ 흐름이 μƒλ‹¨μ—μ„œλ§Œ μ‘°ν•©λ˜κΈ° λ•Œλ¬Έμ—, μƒˆλ‘œμš΄ μš”κ΅¬μ‚¬ν•­μ„ λ°˜μ˜ν•˜κΈ° μ‰¬μ›Œμ§„λ‹€.

κ·Έλž˜μ„œ 결둠은?

이번 κΈ€μ—μ„œλŠ” λ³΅μž‘ν•œ μ΄λ‘ λ³΄λ‹€λŠ” μ‹€μ œ ν”„λ‘œμ νŠΈμ—μ„œ 느꼈던 'μ˜μ‘΄μ„± 섀계'의 μ€‘μš”μ„±μ— λŒ€ν•΄ μ •λ¦¬ν•΄λ³΄μ•˜λ‹€.

 

μš°λ¦¬λŠ” ν”νžˆ μ•„ν‚€ν…μ²˜λ₯Ό 이야기할 λ•Œ 계측을 λ‚˜λˆ„λŠ” 데에 μ§‘μ€‘ν•˜μ§€λ§Œ, μ •μž‘ μ€‘μš”ν•œ 건 λˆ„κ°€ λˆ„κ΅¬λ₯Ό μ˜μ‘΄ν•  수 μžˆλŠ”κ°€μ— λŒ€ν•œ κ·œμΉ™μ„ μ„Έμš°λŠ” 일도 ꡉμž₯히 μ€‘μš”ν•˜λ‹€κ³  μƒκ°ν•œλ‹€.

 

λ‚΄κ°€ μƒκ°ν•˜λŠ” 핡심은 μ•„λž˜ 두 가지닀:

  1. 도메인 λ‘œμ§μ€ μ™ΈλΆ€ κ΅¬ν˜„μ— 영ν–₯을 받지 μ•Šλ„λ‘ μˆœμˆ˜ν•˜κ²Œ μœ μ§€ν•΄μ•Ό ν•œλ‹€.
  2. μ™ΈλΆ€ μ‹œμŠ€ν…œκ³Όμ˜ 연결은 λͺ…ν™•ν•˜κ²Œ λΆ„λ¦¬ν•˜κ³  μΊ‘μŠν™”ν•΄μ•Ό ν•œλ‹€.

λ¬Όλ‘  ν”„λ‘œμ νŠΈμ˜ 성격, 규λͺ¨, νŒ€ 문화에 따라 더 λ‚˜μ€ λŒ€μ•ˆμ΄ μžˆμ„ μˆ˜λ„ μžˆλ‹€. ν•˜μ§€λ§Œ ν˜„ μ‹œμ μ—μ„œ λ‚΄κ°€ λŠλ‚€ κ°€μž₯ μ‹€μš©μ μΈ λ°©ν–₯은 이 정도 μ„ μ΄μ—ˆλ‹€.

 

λ§λΆ™μ΄μžλ©΄, 이 글은 클린 μ•„ν‚€ν…μ²˜λ‚˜ ν—₯사고날 섀계 같은 νŠΉμ • μ•„ν‚€ν…μ²˜ νŒ¨ν„΄μ„ 깊이 있게 μ΄μ•ΌκΈ°ν•˜κΈ°λ³΄λ‹¨, 그보닀 λ¨Όμ € κ³ λ―Όλ˜μ–΄μ•Ό ν•  μ˜μ‘΄μ„± μ„€κ³„μ˜ μš°μ„ μˆœμœ„μ— λŒ€ν•΄ 기둝해두고 μ‹Άμ–΄μ„œ μž‘μ„±ν–ˆλ‹€. ꡬ쑰적인 선택 μ—­μ‹œ μ€‘μš”ν•˜μ§€λ§Œ 이런 점듀을 κ³ λ €ν•˜κ³  해도 μ’‹λ‹€κ³  μƒκ°ν•œλ‹€.

 

κ·Έλž˜μ„œ, μ•žμœΌλ‘œ ν”„λ‘œμ νŠΈλ₯Ό μ‹œμž‘ν•  λ•ŒλŠ” 'κΈ°λŠ₯을 μ–΄λ–»κ²Œ λ‚˜λˆŒκΉŒ?'도 μ€‘μš”ν•˜μ§€λ§Œ 'λˆ„κ°€ λˆ„κ΅¬λ₯Ό μ˜μ‘΄ν•  수 μžˆμ„κΉŒ?'도 깊게 κ³ λ―Όν•˜λ €κ³  ν•œλ‹€.

'μ•„ν‚€ν…μ²˜' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

πŸ’« μ†Œν”„νŠΈμ›¨μ–΄ μ•„ν‚€ν…μ²˜ with 도메인  (1) 2024.02.12