Notice
Recent Posts
Recent Comments
Link
«   2025/08   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
Archives
Today
Total
관리 메뉴

안드로이드 개발일기

[Clean Architecture] UseCase를 사용하는 이유 본문

android

[Clean Architecture] UseCase를 사용하는 이유

lolvlol 2023. 12. 14. 20:50

UseCase는 domain 영역으로, 유저가 요청하는 동작을 수행하여 유저가 해당 서비스를 통해 하고자 하는 것을 의미합니다.

주로 UseCase에는 ViewModel이 Repository의 메소드를 호출하는 코드가 들어가며, 로직을 캡슐화 합니다.

 

저는 BaseUseCase를 두고, 이를 상속하여 UseCase 클래스를 구현합니다.

 

abstract class BaseUseCase<in P, R>() {
    suspend operator fun invoke(params: P): ResultData<R> {
        return try {
            execute(params)
        } catch (e: Exception) {
            ResultData.Error(errorMessage = e.toString())
        }
    }

    protected abstract suspend fun execute(params: P): ResultData<R>
}
class GetLectureListUseCase(
    private val lectureRepository: LectureRepository
): BaseUseCase<GetLectureListUseCase.Params, LectureListResponse>() {
    override suspend fun execute(params: Params): ResultData<LectureListResponse> {
        return lectureRepository.getLectureList(params)
    }

    data class Params(
        val id: Long,
        val offset: Int = 0,
        val count: Int = 10
    )
}
class DetailViewModel(
    ...
    private val getLectureListUseCase: GetLectureListUseCase
) : BaseMviViewModel<DetailContract.State, DetailContract.Event, DetailContract.Effect>() {

    private fun requestGetLecture() {
        viewModelScope.launch {
            getLectureListUseCase(
                GetLectureListUseCase.Params(
                    id = courseId,
                    offset = lectureOffset,
                    count = pageCount
                )
            ).let {
                when (it) {
                    is ResultData.Success -> {
                        ...
                    }

                    is ResultData.Error -> {
                        ...
                    }
                }
            }
        }
    }
}

 

UseCase에는 repository의 메소드를 호출하는 코드 밖에 없습니다.

ViewModel에서 Repository를 호출하면 되는데 왜 1 depth 추가하여 UseCase로 사용하는 것일까요?

 

UseCase의 사용 이유

1. 코드의 일관성

프로젝트 내 어떤 개발자는 ViewModel에서 UseCase를 호출하고, 또 다른 개발자는 Repository를 직접 접근하도록 코드를 작성한다면 일관성이 깨집니다. 그래서 Clean Architecture에 따라 UseCase를 사용하도록 하여 일관성과 코드의 이해도를 높입니다.

 

2. 관심사 분리

ViewModel이 presentation layer의 역할과 data layer의 역할을 모두 수행하여 God Object가 되는 것을 피해야 합니다.

Repository를 사용한다는 것은 data layer의 기능을 알아야 한다는 것을 의미합니다.

UseCase를 사용하여 ViewModel이 하는 역할을 줄일 수 있습니다.

 

3. 요구사항이 변경될 때 쉽게 적용하기 위함

repository.doSomething()을 사용하는 ViewModel이 5개이라고 가정합니다.

그리고 위 메소드를 사용하기 위해 repository2.mustDo()가 먼저 호출되어야 하는 변경사항이 생겼다고 가정합니다.

UseCase를 사용하지 않는다면 5개의 클래스를 수정해주어야 하지만, UseCase를 사용한다면 UseCase 한 곳만 수정하면 됩니다.

이는 클린 아키텍처의 목적 중 하나인 요구사항이 변경될 때 쉽게 적용할 수 있는 코드 베이스를 제공하게 됩니다.

 

4. 프로젝트 앱이 어떤 기능을 하는지 이해하기 위함

프로젝트를 열었을 때 앱이 어떤 기능을 하는지 아래처럼 UseCase가 있으면 더 이해하기 편합니다.

UseCase가 없다면 ViewModel을 직접 열어보며 확인해야할 것입니다.

https://proandroiddev.com/why-you-need-use-cases-interactors-142e8a6fe576

 

5. 재사용성

Repository를 호출하는 ViewModel이 많은 경우 UseCase를 사용하는 것이 코드를 최소화하고 재사용성을 높일 수 있습니다.

Comments