Обобщенная функция, чтобы избежать повторяемости - PullRequest
1 голос
/ 19 сентября 2019

Я хочу иметь обобщенную функцию для моего метода репозитория, которая выполняет вызов API.Вот код -

RemoteInterface.java

interface RemoteInterface {

    @GET("...")
    suspend fun getRandomImage(): MyModel

    @GET(".../{id}/...")
    suspend fun getRandomImageById(@Path("id") id: String): MyModel
}

Теперь мой класс репозитория выглядит так -

override suspend fun getImageFromRemote(): MyResult {
        if (util.checkDeviceInternet()) {
            try {
                val result = remoteInterface.getRandomImage()
                if (result.status == "200") {
                    return MyResult.Content(result)
                } else {
                    return MyResult.Error(MyResult.ErrorType.API_ERROR)
                }
            } catch (e: Exception) {
                return MyResult.Error(MyResult.ErrorType.API_ERROR)
            }
        } else {
            return MyResult.Error(MyResult.ErrorType.NO_INTERNET)
        }
    }

    override suspend fun getImageByIdFromRemote(id: String): MyResult {
        if (util.checkDeviceInternet()) {
            try {
                val result = remoteInterface.getRandomImageById(id)
                if (result.status == "200") {
                    return MyResult.Content(result)
                } else {
                    return MyResult.Error(MyResult.ErrorType.API_ERROR)
                }
            } catch (e: Exception) {
                return MyResult.Error(MyResult.ErrorType.API_ERROR)
            }
        } else {
            return MyResult.Error(MyResult.ErrorType.NO_INTERNET)
        }
    }

Как видите, мои 2 метода в репозитории повторяютсяфункция тела.Можно ли как-нибудь написать обобщенную функцию, которая выполняет те же функции, что и эти две функции?

Ответы [ 2 ]

2 голосов
/ 19 сентября 2019

Вы можете использовать встроенную функцию, чтобы сделать это, с нулевыми накладными расходами.

private inline fun usefulFunction(block: () -> MyModel): MyResult {
    if (util.checkDeviceInternet()) {
        try {
            val result = block()
            if (result.status == "200") {
                return MyResult.Content(result)
            } else {
                return MyResult.Error(MyResult.ErrorType.API_ERROR)
            }
        } catch (e: Exception) {
            return MyResult.Error(MyResult.ErrorType.API_ERROR)
        }
    } else {
        return MyResult.Error(MyResult.ErrorType.NO_INTERNET)
    }
}

тогда в ваших функциях репозитория вы можете сделать.

override suspend fun getImageFromRemote(): MyResult {
    return usefulFunction {
        remoteInterface.getRandomImage()
    } 
}

override suspend fun getImageByIdFromRemote(id: String): MyResult {
    return usefulFunction {
        remoteInterface.getRandomImageById(id)
    }
}
0 голосов
/ 19 сентября 2019

Вы можете удалить блок try{}catch{} и заменить его на CoroutineExceptionHandler:

val coroutineExceptionHandler = CoroutineExceptionHandler{_,_ -> return MyResult.Error(MyResult.ErrorType.API_ERROR)
}

coroutineScope.launch(coroutineExceptionHandler ){
  val result = getImageFromRemote()
}
...