Android usecase 적용기

Assist·2023년 7월 3일
0

Android

목록 보기
13/24

오늘은 이전에 저의 멘토님께서 말씀하신 usecase을 적용을 해볼려고 코드 간결성 이 얼마나 좋아졌는지 보겠습니다.

usecase

왜 usecase을 써야 하는가

이건 이전에 제가 멘토님에게 질문했던것이랑 똑같았고 적용 이전까지도 의문 이었습니다.

Assist : usecase을 적용하면 MVVM 패턴 같은 경우는 ViewModel 이 비즈니스 로직을 담당한다고 나와있는데 그럼 viewModel 은 LiveData만 하는거 아닌가요?
멘토님 : 네 맞아요
Asisst : ?
멘토님 : 그것또한 viewModel 에 책임이죠. 비즈니스 로직을 viewModel 에 적용해도 상관은 없어요
단 viewModel 에 비즈니스 로직이 1천줄 넘어가면 그 프로그램은 나중에 더 쉽게 기능 추가나 유지보수를 할수 있을까요?

대충 이런 대화 였습니다 .

그럼 한번 적용해보러 가보겠습니다

  • hilt 라이브러리를 쓴다
  • Repository 은 interface 로 선언한다
  • Repositoryimpl(구현체)에 메소드로 usecase을 선언한다

Hilt 로 Respoitory 을 넘겨보자

일단 Repository을 interface으로 선언 해본다고 생각을 해보겠습니다 .

@HiltViewModel
class viewModel @Inject constructor (private val repository : Repository) : ViewModel 

여기에 문제점은 무엇일까요

바로

viewModel : .... interface 만 넘기면 어쪄자고!!!!

라고 나올것 입니다

보통 Factory을 선언하면

val facotry = viewModelFactory(repositoryImpl) 

이런식으로 넘기니 구현체가 무엇인지 알기 때문이죠
그럼 Hilt으로는 답이 없는가

아닙니다 더 쉽습니다

@Module
@InstallIn(SingletonComponent :: class)
object RepositoryModule {

    @Provides
    @Singleton
    fun provideRepository( useCase: MainUseCase) : Repository {
        return MainRepositoryImpl(useCase)
    }


}

이런식으로 한번에 클래스를 선언해 버리면 끝납니다

이게 무슨뜻이냐
싱글톤으로 만들어서 모듈 형식으로 MainRepository 에 usecase을 넘겨주고 바로 viewModel에 넘겨주지요

--사실 쫌더 조사해서 댓글에 적어 두겠습니다. 아직 조사중이라...---

그럼 repository에도 usecase을 넘겨줫으니 그럼 한번 사용을 해보면

class MainRepositoryImpl @Inject constructor(private val useCase : MainUseCase) : Repository{

   override suspend fun useUseCase (data: token , page: Int, pageSize: Int, key: String) {

        val getWardRoom = RetrofitInterface.requestBaseUrl().testUsecase (data.token , data.customerId , page  , pageSize , key)

        getUsecaseData.enqueue(object : Callback<Any> {
            override fun onResponse(call: Call<Any>, response: Response<Any>) {
                when(response.code()){
                    Define.CALL_SUCCESS ->{
                        val data = response.body()
                        if(data == null) {
                            usecaseLiveData.postValue(Resource.error(Define.MESSAGE_DATA_NULL))
                            return
                        }
       
                        val reformData = useCase.usecase(data as String) -> 원래는 따로 private 을 선언 해둔것 

                         usecas1  = useCase.reformData0(reformData) -> 원래는 따로 private 을 선언 해둔것 
                         usecas2  = useCase.reformData1(reformData) -> 원래는 따로 private 을 선언 해둔것 
//                   
                        usecaseLiveData.postValue(Resource.success(UseCaseData(usecas1 , usecas2)))
                    }
                    Define.CALL_EXPIRE_TOKEN ->{
                       usecaseLiveData.postValue(Resource.error(Define.MESSAGE_TOKEN_EXPIRE))
                    }
                    else ->usecaseLiveData.postValue(Resource.error(Define.MESSAGE_DATA_NULL))
                }
            }

            override fun onFailure(call: Call<Any>, t: Throwable) {
                usecaseLiveData.postValue(Resource.error(Define.MESSAGE_FAIL))
            }
        })
    }
    }

상당히 클린 코드에 가까워 지는거 같습니다.

덕분에 repository와 viewModel에 따로 비즈니스 로직을 안적어도 되어서 코드가 상당히 깔끔해지는 현상을 볼수 잇습니다.

그럼 오늘도 읽어주셔서 감사합니다

-피드백와 빞나은 언제나 환영입니다-

profile
안드로이드만 좋아하는 특이한 개발자

0개의 댓글

관련 채용 정보