Extract retry logic into higher order function from previous Coroutine

2024. 8. 25. 00:30·Language/Kotlin
728x90
반응형

이번 글에서는 저번 Coroutine retry 로직을 구현했던 것을 고차함수로 추출해내는 작업을 해볼 예정이다.

 

Step1. 초안 작성하기

fun retry(numberOfRetries: Int, block: () -> Unit) {
	repeat(numberOfRetries) {
    	try {
        	block()
        } catch (e: Exception) {
        	e.printStackTrace()
        }
    }
    block()
}

초안을 작성해보면 위와 같은 코드가 된다.

 

얼핏 보기엔 문제가 없을 것 같지만, 파라미터 전달될 함수 리턴 타입을 알 수 없기에 Unit 하나로 제한해버리면 안된다.

 

이럴 때 생각나는 녀석이 하나 있는데 바로 제네릭(Generic)이다.

 

Step2. 제네릭을 포함하는 함수로 바꾸기

fun <T> retry(numberOfRetries: Int, block: () -> T) {
	repeat(numberOfRetries) {
    	try {
			return block()
        } catch (e: Exception) {
        	e.printStackTrace()
        }
    }
    return block()
}

이렇게 코드를 변경해주면 파라미터로 전달될 함수의 자료형을 모두 수용할 수 있게 된다.

 

Step3. 이제 적용해보기

이전 글을 읽어보지 않은 사람들을 위해 설명하자면 나는 retry logic을 viewModelScope에서 실행하도록 만들어 뒀었다.

 

그래서 아래와 같은 코드로 진행될 것이다.

 

viewModelScope.launch {
	val numberOfRetries = 2
    try {
    	retry(numberOfRetries) {
        	loadRecentVersion()
        }
    } catch (e: Exception) {
    	e.printStackTrace()
    }
}

이렇게 되면 문제없이 끝날 것으로 예상했다.

 

다만, loadRecentVersion()과 같이 파라미터로 전달될 함수가 suspend fun인 경우에는 어떻게 해야할까?

 

Step4. Suspend 가능 함수로 변경하기

suspend fun <T> retry(numberOfRetries: Int, block: suspend () -> T) {
	repeat(numberOfRetries) {
    	try {
			return block()
        } catch (e: Exception) {
        	e.printStackTrace()
        }
    }
    return block()
}

retry 함수와 파라미터에 전달될 함수에 suspend 키워드를 추가해주었다.

 

먼저 파라미터만 suspend 키워드를 추가해주면 함수 내부 return 문에서 에러가 나게 된다.

 

return하게 될 block()은 suspend fun에서만 실행될 수 있다고 말이다.

 

그리하여 함수 자체에도 suspend 키워드가 추가되었다.

 

이렇게 되면 이전 코드 예시처럼 viewModelScope에서 문제없이 함수를 실행할 수 있다.

 

결과적으로 얻은 이득

첫번째로는 당연히 ViewModelScope에서 실행하는 코드 라인이 짧아졌다.

(엄밀히 따지면 현재 해당 함수는 따로 빠져 있으니 코드 전체 길이는 큰 차이가 없다.

그래도 같은 retry logic이 여기저기서 반복될 수록 전체 코드는 짧아진다.)

 

두번째로는 또 당연하게도 재사용성이 좋아졌다.

 

고차함수를 적용하며 제네릭을 사용하니

어떠한 작업이라도 같은 함수를 사용하면 똑같이 원하는 수만큼 retry logic을 적용시킬 수 있다.

728x90
반응형
저작자표시 비영리 변경금지 (새창열림)

'Language > Kotlin' 카테고리의 다른 글

CoroutineContext와 CoroutineScope 알아보기  (1) 2024.09.04
Coroutines on Main Thread(위험성에 대해 인지하기)  (0) 2024.09.03
Implement Coroutines Retry  (1) 2024.06.05
Implement Coroutines Timeout  (0) 2024.05.29
async CoroutineBuilder Introduction  (0) 2024.05.27
'Language/Kotlin' 카테고리의 다른 글
  • CoroutineContext와 CoroutineScope 알아보기
  • Coroutines on Main Thread(위험성에 대해 인지하기)
  • Implement Coroutines Retry
  • Implement Coroutines Timeout
BonusTrack02.dev
BonusTrack02.dev
공부, 일상
  • BonusTrack02.dev
    BonusTrack02.dev
    BonusTrack02.dev
  • 전체
    오늘
    어제
    • 분류 전체보기 (237)
      • Android (84)
      • Language (63)
        • Java (19)
        • Kotlin (27)
        • Swift (17)
      • 프로그래머스 (68)
      • 주저리주저리 (22)
        • 카페 (5)
        • 음식점 (4)
        • 컨퍼런스 (1)
        • 팝업스토어 (4)
        • 해외여행 (0)
        • 전시회 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    LiveData
    databinding
    Java
    PCCE
    Observer
    coroutines
    SWIFT
    코틀린
    viewModelScope
    안드로이드
    aac
    ViewModel
    getNumericValue
    코루틴
    Material
    programmers
    room
    jetpack
    MVVM
    android
    스위프트
    프로그래머스
    Kotlin
    daterangepicker
    배열
    오블완
    ios
    자바
    티스토리챌린지
    CodeLab
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
BonusTrack02.dev
Extract retry logic into higher order function from previous Coroutine
상단으로

티스토리툴바