Paging3 클린 아키텍처 적용
Paging3를 클린 아키텍처에 적용하다가 의문점이 생겼다.
Domain 레이어에 있는 androidx.paging이 안드로이드 종속성이 있지 않나?
사용하면 안되지 않나?
그래서 찾아 보았다.
클린 아키텍처에서 Paging 3의 역할
각 계층의 역할
Paging 3의 안드로이드 종속성 정리
Paging 3은 여러 개의 모듈로 나뉘어 있으며, 각 모듈이 제공하는 기능을 이해해야 한다.
📌 1. androidx.paging:paging-common (안드로이드 종속성 없음 ✅)
implementation "androidx.paging:paging-common:3.x.x"
✔ 멀티플랫폼(Kotlin Multiplatform)에서도 사용 가능
✔ 안드로이드 종속성이 없으며, Domain 계층에서도 사용할 수 있음
📌 포함된 주요 클래스
- PagingData
- PagingSource
- PagingConfig
- LoadResult
- RemoteMediator
📌 Domain 계층에서도 사용 가능!
👉 이 모듈에 포함된 클래스는 Android에 종속되지 않으므로, UseCase에서도 PagingData를 유지할 수 있다.
📌 2. androidx.paging:paging-runtime (안드로이드 종속성 있음 🚨)
implementation "androidx.paging:paging-runtime:3.x.x"
✔ 안드로이드 종속성이 있음 → Data 계층 및 Presentation 계층에서만 사용 가능
✔ Pager 및 PagingDataAdapter와 같은 Android 특정 기능이 포함됨
📌 포함된 주요 클래스
- Pager
- PagingDataAdapter
- PagingSourceFactory
- cachedIn(viewModelScope)
📌 이 모듈에 포함된 클래스는 Android 종속적이므로, Domain 계층에서는 사용하면 안 된다.
👉 특히 Pager는 Repository에서만 사용해야 한다.
📌 3. androidx.paging:paging-compose (Compose UI 관련, 안드로이드 종속성 있음 🚨)
implementation "androidx.paging:paging-compose:3.x.x"
✔ Jetpack Compose에서 Paging을 사용할 때 필요한 모듈
✔ Compose UI 계층에서만 사용 가능
✔ 안드로이드 종속성이 있으므로 Domain 및 Data 계층에서는 사용 불가
📌 포함된 주요 클래스
- LazyPagingItems
- collectAsLazyPagingItems()
- LazyColumn { items(lazyPagingItems) }
📌 이 모듈은 UI 계층에서만 사용해야 하며, Repository나 UseCase에서 사용하면 안 된다.
클린 아키텍처에서 Paging 3을 올바르게 적용하는 방법
1. Repository에서 PagingData 제공 (Data Layer)
class MyRepository(private val apiService: MyApiService) {
fun getPagedData(): Flow<PagingData<MyData>> {
return Pager(
config = PagingConfig(pageSize = 20),
pagingSourceFactory = { MyPagingSource(apiService) }
).flow
}
}
✔ Pager는 안드로이드 종속성이 있으므로 Repository에서만 사용.
✔ 반환값이 Flow<PagingData<MyData>>이므로 Domain에서도 사용할 수 있음.
2. UseCase에서 PagingData를 그대로 전달 (Domain Layer)
class GetPagedDataUseCase(private val repository: MyRepository) {
operator fun invoke(): Flow<PagingData<MyData>> {
return repository.getPagedData()
}
}
✔ UseCase에서도 PagingData를 그대로 유지할 수 있음!
✔ PagingData는 안드로이드 종속성이 없으므로 Domain 계층에서도 사용 가능!
3. ViewModel에서 PagingData 처리 (Presentation Layer)
@HiltViewModel
class MyViewModel @Inject constructor(
private val getPagedDataUseCase: GetPagedDataUseCase
) : ViewModel() {
val myPagingData: Flow<PagingData<MyData>> = getPagedDataUseCase()
.cachedIn(viewModelScope) // ViewModel에서 캐싱 유지
}
✔ 여기서 cachedIn(viewModelScope)를 적용해야 UI에서 collectAsLazyPagingItems()로 사용할 수 있음.
✔ 이 부분은 안드로이드 종속성이 있으므로 반드시 ViewModel에서 처리해야 함.
정리
📌 결론:
✔ PagingData, PagingSource, PagingConfig는 Domain 계층에서도 사용할 수 있다.
✔ Pager, LazyPagingItems, cachedIn()은 Android 종속성이 있으므로 UI나 Repository에서만 사용해야 한다.
✔ UseCase에서는 PagingData를 그대로 유지하면 된다. (변환할 필요 없음!)
참조 :
https://medium.com/bforbank-tech/paging-3-through-clean-architecture-4d771ab19fa8
https://leveloper.tistory.com/208
'코틀린 & 컴포즈 & Java > 컴포즈 Compose' 카테고리의 다른 글
[Compose] LiveData vs StateFlow: Compose에서 어떤 것을 사용할까? (0) | 2025.02.06 |
---|---|
[Compose] Compose에서 key의 역할과 사용법 (0) | 2025.02.06 |
[Compose] TextField의 여백 문제와 해결 방법 (0) | 2025.02.06 |
[Compose] Compose에서 =와 by의 차이 (kotilin 동일) (0) | 2025.02.05 |
[Compose] Modifier의 위치와 적용 규칙 (0) | 2025.02.05 |