λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
  • μž₯원읡 κΈ°μˆ λΈ”λ‘œκ·Έ
πŸ”¬application/- DDD

[DDD] Repository Pattern μ΄λž€, 이둠편

by Wonit 2022. 8. 23.

이 글은 이둠과 μ‹€μŠ΅, 두 파트둜 λ‚˜λ‰˜μ–΄μ Έ μžˆμŠ΅λ‹ˆλ‹€.

 

  1. Repository Pattern 에 λŒ€ν•΄μ„œ, 이둠편 <- ν˜„μž¬ κΈ€
  2. Repository Pattern - μ‹€μ „νŽΈ (Spring μ—μ„œ DIP λ₯Ό 톡해 Repository 의 μ„ μ–Έκ³Ό κ΅¬ν˜„ λΆ„λ¦¬μ‹œν‚€κΈ°)

 

λͺ©μ°¨

  • μ„œλ‘ 
  • Repository Pattern
  • DIP 와 Repository
  • DDD κ΄€μ μ˜ Repository λŠ”?

 

μ„œλ‘ 

 

Spring Data JPA λ₯Ό μ‚¬μš©ν•œλ‹€λ©΄ κ°€μž₯ 많이 μ ‘ν•˜λŠ” 것이 λ°”λ‘œ Repository κ°€ μ•„λ‹κΉŒ μ‹Άλ‹€.

 

이 Repository λΌλŠ” κ°œλ…μ€ JPA μ—μ„œ μ‚¬μš©λ˜λŠ” μΈν„°νŽ˜μ΄μŠ€κ°€ μ•„λ‹ˆλΌ Spring Data μ—μ„œ μ‚¬μš©λ˜λŠ” μΈν„°νŽ˜μ΄μŠ€μ΄λ‹€.

 

μš°λ¦¬λŠ” νŠΉμ • 도메인 객체λ₯Ό μ§€μ†μ μœΌλ‘œ μ‚¬μš©ν•˜κΈ° μœ„ν•΄μ„œ (ν˜Ήμ€ μ˜μ†ν•˜κΈ° μœ„ν•΄) μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ§€νƒ±ν•˜λŠ” Backing Service 에 μ˜μ†ν•΄μ•Ό ν•œλ‹€.

 

그게 RDBMS λ‚˜ NoSQL, λ‘œμ»¬μ— μ‘΄μž¬ν•˜λŠ” 파일 ν˜Ήμ€ remote 의 μ–΄λ”˜κ°€λ˜ 물리적인 μ €μž₯μ†Œκ°€ ν•„μš”ν•˜λ‹€.

 

κ·Έλž˜μ„œ spring-data-jpa, spring-data-jdbc, spring-data-elasticsearch λ₯Ό λ§‰λ‘ ν•˜κ³  repository λ₯Ό ν†΅ν•΄μ„œ μ˜μ†μ„± μž₯μΉ˜μ™€ 톡신을 ν•˜κ²Œ λœλ‹€.

 

μ΄λŸ¬ν•œ Repository λŠ” 사싀 Spring 의 κ°œλ…μ€ μ•„λ‹ˆλ©° μ—­μ‹œ Javaλ‚˜ μ–΄λ–€ κ΅¬ν˜„ κΈ°μˆ μ— 쒅속적인 이야기 μ—­μ‹œλ„ μ•„λ‹ˆλ‹€.

 

Spring-Data λͺ¨λ“ˆ μ—­μ‹œ repository λΌλŠ” κ°œλ…μ— μ˜ν•΄μ„œ μ‹œμž‘λ˜μ—ˆκ³  μ˜€λŠ˜μ€ 그에 λŒ€ν•΄μ„œ μ•Œμ•„λ³΄λ € ν•œλ‹€.

 

Repository Pattern

 

Repository Pattern 은 2004 λ…„ Eric Evans 의 Domain-Driven-Design μ—μ„œ 처음 μ†Œκ°œλœ κ°œλ…μœΌλ‘œ, 곡톡적인 데이터 Access & Manipluate 에 μ§‘μ€‘ν•˜μ—¬ 도메인 λͺ¨λΈ 계측과 κ΅¬ν˜„ κΈ°μˆ μ„ λΆ„λ¦¬μ‹œν‚€λŠ” 것을 μ˜λ―Έν•œλ‹€.

 

 

μ΄λ ‡κ²Œ ν•¨μœΌλ‘œμ¨ RDB λ‚˜ Query 와 같이 μ–΄λ– ν•œ κ΅¬ν˜„ κΈ°μˆ μ— 쒅속적이지 μ•Šκ³  도메인에 λ”μš± 집쀑할 수 있게 λ˜λŠ” νŒ¨ν„΄μ„ μ˜λ―Έν•œλ‹€.

Repository 에 λŒ€ν•΄μ„œ Martin Fowler λŠ” λ‹€μŒκ³Ό 같이 ν‘œν˜„ν•œλ‹€.

 


A repository performs the tasks of an intermediary between the domain model layers and data mapping, acting in a similar way to a set of domain objects in memory. Client objects declaratively build queries and send them to the repositories for answers. Conceptually, a repository encapsulates a set of objects stored in the database and operations that can be performed on them, providing a way that is closer to the persistence layer. Repositories, also, support the purpose of separating, clearly and in one direction, the dependency between the work domain and the data allocation or mapping.

 

즉 ν•œ λ¬Έμž₯으둜 μš”μ•½ν•˜μžλ©΄ λ‹€μŒκ³Ό κ°™λ‹€.

 

Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.

 

즉, domain κ³Ό data source layer 간에 μ€‘μž¬μž 역할을 μˆ˜ν–‰ν•˜λŠ” 것이라고 ν•œλ‹€.

 

repository λŠ” μ˜μ†μ„± μž₯μΉ˜μ—μ„œ 쿼리의 결과둜 λ°›μ•„μ˜¨ 데이터λ₯Ό repository μ—μ„œλŠ” domain μ—μ„œ μ‚¬μš©ν•˜κΈ° μ ν•©ν•˜λ„λ‘ Domain 객체둜 mapping ν•˜λŠ” 역할을 μˆ˜ν–‰ν•œλ‹€.

 

 

μœ„ 그림은 Jpa λ₯Ό μ‚¬μš©ν•  λ–„ 기본으둜 μ‚¬μš©λ˜λŠ” Repository 의 κ΅¬ν˜„μ²΄μΈ (μ •ν™•νžˆλŠ” JpaRepository 의 κ΅¬ν˜„μ²΄) SimpleJpaRepository ν΄λž˜μŠ€μ΄λ‹€.

 

μœ„μ™€ 같이 entity 에 λŒ€ν•œ 정보λ₯Ό 받기도 ν•˜λ©° μ‹€μ œ connection 을 μ²˜λ¦¬ν•  entity manager λ˜ν•œ λ³΄μœ ν•˜κ³  μžˆλŠ” 것을 μ•Œ 수 μžˆλ‹€.

 

κΌ­ μ˜μ†μ„± μž₯치일 ν•„μš”λŠ” μ—†λ‹€.

 

domain κ΄€μ μ—μ„œ 보면 repository 뒀에 μ–΄λ–€ μž₯μΉ˜κ°€ μˆ¨μ–΄μžˆλ˜ 상관 없이 데이터λ₯Ό μ‘°μž‘ν•˜λŠ” 데에 ν•„μš”ν•œ μΈν„°νŽ˜μ΄μŠ€λ§Œμ„ 바라보고 ν˜‘λ ₯ν•˜κΈ° λ•Œλ¬Έμ— RDBMS 이던, WebServer 이던, FileSystem 이던 상관 μ—†λ‹€.

 

DIP 와 Repository

 

DDD μ—μ„œ λ§ν•˜λŠ” Layered Architecture λ₯Ό μ μš©ν•œλ‹€λ©΄ μ•„λ§ˆ λ‹€μŒκ³Ό 같은 ꡬ쑰가 일반적으둜 μ‚¬μš©λ  것이닀.

 

 

κ°€μš΄λ° μžˆλŠ” Infrastructure Persistence Layer κ°€ λ°”λ‘œ Repository κ°€ μ‘΄μž¬ν•˜λŠ” λ ˆμ΄μ–΄μ΄λ‹€.

 

μ•žμ„œμ„œ μ™œ Repository κ°€ μ‘΄μž¬ν•œλ‹€κ³  ν–ˆλŠ”μ§€ κΈ°μ–΅λ‚˜λŠ”κ°€?

 

λ‹€μ‹œ ν•œλ²ˆ λ§ν•˜μžλ©΄ Repository λŠ” 도메인을 μ˜μ†ν™”ν•˜λŠ”λ° ν•„μš”ν•œ μΌμ’…μ˜ λͺ…세이닀.

 

도메인 κ΄€μ μ—μ„œ "λ‚˜λŠ” 이런 것듀을 μ΄λ ‡κ²Œ μ €μž₯ν•  것이고 μ΄λ ‡κ²Œ λΆˆλŸ¬μ˜¬κ±°μ•Ό!" λΌλŠ” λͺ…μ„Έλ₯Ό λ§Œλ“€μ–΄λ†“κ³  μ‹€μ œ κ΅¬ν˜„ κΈ°μˆ μ— λŒ€ν•œ 뢀뢄을 λΆ„λ¦¬μ‹œν‚¨λ‹€λŠ” 것이닀.

 

κ·Έλž˜μ„œ μœ„μ˜ Domain Model Layer 와 Infrastructure Layer λ₯Ό λ‚˜λˆ„λŠ” 것도 같은 λ§₯락이닀.

 

  • Domain Model Layer μ—μ„œλŠ” μ €μž₯ν•˜λŠ” 방법에 λŒ€ν•΄μ„œ 관심을 κ°–κ³ ,
  • Infrastructure Layer μ—μ„œλŠ” μ‹€μ œλ‘œ μ–΄λ–»κ²Œ μ €μž₯ν•˜λŠ”μ§€μ— λŒ€ν•΄μ„œ 관심을 κ°–λŠ”λ‹€.

 

이 λ‘˜ 사이λ₯Ό μ–΄λ–»κ²Œ κ΅¬ν˜„ν• κΉŒ?

 

정닡은 DIP 이닀.

 

DIP λ₯Ό μ΄μš©ν•΄μ„œ 도메인 λͺ¨λΈμ— μ‘΄μž¬ν•˜λŠ” Repository μΆ”μƒν™”λ‘œ λ§Œλ“€κ³  μ‹€μ œ κ΅¬ν˜„μ„ infrastructure μ—μ„œ ν•˜κ²Œ ν•œλ‹€.

 

DIP λ₯Ό μ‚¬μš©ν•œλ‹€λŠ” 것은 의쑴의 λ°©ν–₯을 μ—­μ „μ‹œν‚€κ² λ‹€λŠ” 이야기닀.

 

즉, κ³ μˆ˜μ€€ λͺ¨λ“ˆ(의미 μžˆλŠ” 단일 κΈ°λŠ₯)이 μ €μˆ˜μ€€ λͺ¨λ“ˆ(κ³ μˆ˜μ€€ λͺ¨λ“ˆμ„ κ΅¬ν˜„ν•˜κΈ° μœ„ν•œ κΈ°λŠ₯)에 μ˜μ‘΄ν•˜μ§€ μ•Šλ„λ‘ ν•˜κΈ° μœ„ν•¨μΈλ°, 단지 μ„ μ–Έκ³Ό κ΅¬ν˜„μ„ 뢄리 쯀으둜 μƒκ°ν•œλ‹€λ©΄ 잘λͺ»λœ DIP 의 κ²°κ³Όκ°€ λ‚˜μ˜¬ 수 μžˆλ‹€.

 

예λ₯Ό λ“€λ©΄ μ•„λž˜μ™€ 같은 ν˜•νƒœλ‘œ 말이닀.

 

 

μ΄λ ‡κ²Œ λœλ‹€λ©΄ Repository λ₯Ό λ‹€μ–‘ν•œ ν˜•νƒœμ˜ κ΅¬ν˜„μœΌλ‘œ λ‹€ν˜•μ μ΄κ²Œ λ§Œλ“ λ‹€λŠ” 쑰건은 λ§Œμ‘±μ‹œμΌ°λ‹€.

 

ν•˜μ§€λ§Œ μ—¬μ „νžˆ κ³ μˆ˜μ€€ λͺ¨λ“ˆμ΄ μ €μˆ˜μ€€ λͺ¨λ“ˆμ— μ˜μ‘΄ν•˜κ³  μžˆλ‹€. 즉, 의쑴의 κ΄€μ μ—μ„œ λ³Έλ‹€λ©΄ OrderDomainService κ°€ infrastructure λ₯Ό μ•Œκ²Œ λ˜λŠ” ν˜•νƒœμ΄λ‹€.

 

μ΄λ ‡κ²Œ 의쑴의 λ°©ν–₯이 잘λͺ»λœλ‹€λ©΄ λ§Žμ€ 고톡이 λ°œμƒν•  수 μžˆλ‹€. ν˜„μž¬λŠ” μ΄μƒμ—†λŠ”κ²ƒ 처럼 λ³΄μ΄κ² μ§€λ§Œ ν•œ ν•΄κ°€ μ§€λ‚˜κ³ , λ‹€μŒ ν•΄κ°€ μ§€λ‚˜μ„œ λ‹€λ₯Έ κ°œλ°œμžκ°€ 도메인 λ‘œμ§μ—μ„œ Repository λ₯Ό 좔상적인 것에 μ˜μ‘΄ν•˜λŠ” 게 μ•„λ‹ˆλΌ ꡬ체적인 ElasticsearchRepository λ₯Ό μ˜μ‘΄ν–ˆλ‹€κ³  ν•΄λ³΄μž. 그리고 κ·Έ λ‹€μŒν•΄μ— λΉ„μ¦ˆλ‹ˆμŠ€κ°€ λ³€κ²½λ˜μ–΄ μ €μž₯ν•  ν•„μš” 없이 단지 API 둜 λ‹€λ₯Έ 곳에 relay 만 ν•œλ‹€κ³  ν–ˆμ„λ•Œ, 이듀을 λΆ„λ¦¬ν•˜λŠ” 것은 또 λ‹€λ₯Έ pain point κ°€ 될 것이닀.

 

κ·Έλž˜μ„œ 이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄μ„œ OrderRepository λ₯Ό κ³ μˆ˜μ€€ λͺ¨λ“ˆλ‘œ λ§Œλ“œλŠ” 것이닀.

 

 

μ΄λ ‡κ²Œ λœλ‹€λ©΄ ν•˜λ‚˜μ˜ 좔상적인 Repository 에 λŒ€ν•΄μ„œ λ‹€μ–‘ν•œ κ΅¬ν˜„μ΄ κ°€λŠ₯ν•˜κ²Œ λœλ‹€.

 

 

κ²°κ΅­ Repository λŠ” Jpa μ§„μ˜μ—μ„œ DB 와 μ—°κ²°ν•˜κΈ° μœ„ν•œ layer 둜 λΆ€λ₯΄λŠ” 것이 μ•„λ‹ˆλΌλŠ” 것을 μ•Œ 수 μžˆλ‹€.

 

λ„λ©”μΈμ˜ κ΄€μ μ—μ„œ Repository λŠ” 데이터λ₯Ό μ €μž₯ν•˜λŠ” backing 을 μΆ”μƒν™”ν•œ κ²ƒμœΌλ‘œ 도메인은 μ–΄λ–»κ²Œ Repository 에 μ €μž₯λ˜λŠ”μ§€ 관심을 갖지 μ•ŠλŠ”λ‹€.

 

μ˜€λ‘œμ§€ 도메인 둜직 μžμ²΄μ—λ§Œ 관심을 κ°–λŠ”λ‹€.

 

κ·Έλž˜μ„œ 도메인 κ΄€μ μœΌλ‘œ 보자면 Repository λ₯Ό 두고 infrastructure μ—μ„œ 이λ₯Ό JPA λ₯Ό μ‚¬μš©ν•˜λ˜ MyBatis λ₯Ό μ‚¬μš©ν•΄μ„œ DAO 계측을 λ§Œλ“€κ±΄ μ€‘μš”ν•˜μ§€ μ•Šκ²Œ λ˜λŠ” 것이닀.

 


DDD κ΄€μ μ˜ Repository λŠ”?

 

이제 Domain Driven Design, μ„€κ³„μ˜ κ΄€μ μ—μ„œ Repository λ₯Ό μƒκ°ν•΄λ³΄μž

 

DDD μ—μ„œλŠ” μ• κ·Έλ¦¬κ±°νŠΈλΌλŠ” μš©μ–΄κ°€ μ‘΄μž¬ν•œλ‹€.

 

μ• κ·Έλ¦¬κ±°νŠΈλŠ” κ°„λž΅ν•˜κ²Œ λ§ν•˜μžλ©΄ ν•˜λ‚˜μ˜ unit, λΉ„μ¦ˆλ‹ˆμŠ€ λ‹¨μœ„λ‘œ μ·¨κΈ‰ν•  수 μžˆλŠ” 였브젝트의 집합이닀.

 

예λ₯Ό λ“€μ–΄μ„œ Review λΌλŠ” μ• κ·Έλ¦¬κ±°νŠΈκ°€ μ‘΄μž¬ν•œλ‹€κ³  ν•΄λ³΄μž.

 

그럼 ν•΄λ‹Ή Review λΌλŠ” μ• κ·Έλ¦¬κ±°νŠΈμ—λŠ” λ‹€μŒκ³Ό 같은 μ˜€λΈŒμ νŠΈκ°€ μ‘΄μž¬ν•  것이닀.

 

  • Review μ—λŠ” 글을 μ“΄ μ‚¬λžŒμΈ Reviewer
  • κΈ€μ˜ 본문인 Contents
  • 리뷰의 제λͺ©μΈ Title
  • ν•΄λ‹Ή 리뷰의 Tag

 

이외에도 리뷰λ₯Ό ν‘œν˜„ν•˜λŠ” λ‹€μ–‘ν•œ μ˜€λΈŒμ νŠΈκ°€ μ‘΄μž¬ν•  것인데, ν•΄λ‹Ή μ˜€λΈŒμ νŠΈλŠ” λ¦¬λ·°λΌλŠ” λΉ„μ¦ˆλ‹ˆμŠ€ κ°œλ… ν•˜λ‚˜λ₯Ό κ΅¬μ„±ν•˜λŠ” μš”μ†Œλ“€μ΄λ‹€.

 

κ²°κ΅­ μ–΄λ–€ μ• κ·Έλ¦¬κ±°νŠΈκ°€ μ €μž₯λœλ‹€λŠ” μ†Œλ¦¬λŠ” ν•΄λ‹Ή μ• κ·Έλ¦¬κ±°νŠΈμ— ν¬ν•¨λ˜λŠ” λͺ¨λ“  entity 와 value 듀에 λŒ€ν•΄μ„œ transaction consistency λ₯Ό 보μž₯ν•΄μ•Ό ν•œλ‹€.

 

κ·Έλž˜μ„œ 일반적으둜 DDD μ—μ„œλŠ” ν•˜λ‚˜μ˜ Aggregate λ₯Ό Repository 의 λŒ€μƒ μ—”ν‹°ν‹°λ‘œ μ‚ΌλŠ”λ‹€.

 

즉 Review λΌλŠ” μ• κ·Έλ¦¬κ±°νŠΈκ°€ μ‘΄μž¬ν•  λ•Œ, ν•΄λ‹Ή μ• κ·Έλ¦¬κ±°νŠΈλ₯Ό μ €μž₯ν•˜κ³  λ‘œλ“œν•˜λŠ” Repository λŠ” ReviewRepository 만 μ‘΄μž¬ν•΄μ•Ό ν•œλ‹€λŠ” μ†Œλ¦¬λ‹€.

 

Review κ°€ Tag 듀을 ν¬ν•¨ν•˜κ³  μžˆλ‹€κ³  ν•΄μ„œ TagRepository κ°€ μ‘΄μž¬ν•΄μ„œλŠ” μ•ˆλœλ‹€λŠ” 것이닀.

 

이에 λŒ€ν•΄μ„œ μžμ„Έν•œ μ΄μ•ΌκΈ°λŠ” ν•΄λ‹Ή λΈ”λ‘œκ·Έμ˜ DDD μΉ΄ν…Œκ³ λ¦¬ 의 Aggregate 와 AggregateRoot μ—μ„œ μžμ„Ένžˆ 확인할 수 μžˆλ‹€.

 

끝으둜

 

μ΄λ ‡κ²Œ μ˜€λŠ˜μ€ Repository 에 λŒ€ν•΄μ„œ μ•Œμ•„λ³΄μ•˜λ‹€.

 

μ΅œκ·Όμ— DDD λ₯Ό ν•™μŠ΅ν•˜λ©΄μ„œ μ˜€ν•΄λ₯Ό ν’€κ²Œλœ 것이 Repository λΌλŠ” 것은 κ°œλ…μΈ 것이고 μ–΄λ– ν•œ κΈ°μˆ μ— κ΅­ν•œλœ λ‚΄μš©μ΄ μ•„λ‹ˆλΌλŠ” 것이닀.

 

μ™œ Repository Pattern 이 μ€‘μš”ν•˜κ³  μ–΄λ–€ 것듀을 μ˜€ν•΄ν–ˆλŠ”μ§€ λ§ν•˜λ©΄μ„œ λ‹€μ†Œ 좔상적인 이야기λ₯Ό ν–ˆμ„ μˆ˜λ„ μžˆλ‹€.

 

λ‹€μŒ μ‹œκ°„μ—λŠ” μ‹€μ œλ‘œ Spring μ—μ„œ Repository Pattern 을 κ΅¬ν˜„ν•˜κ³ , DIP λ₯Ό ν†΅ν•΄μ„œ 도메인이 좔상적인 것에 μ˜μ‘΄ν•˜λ„λ‘ λ§Œλ“€μ–΄ λ³Ό μ˜ˆμ •μ΄λ‹€.

 

References

λŒ“κΈ€