Kotlin-作用域函数链

时间:2020-05-18 20:30:29

标签: kotlin

我是Kotlin语言的新手,我想知道拥有一系列作用域函数是否是一个好习惯。例如,我正在编写一个函数,该函数调用一些API(实用函数),解析对特定对象的字符串响应,进行小的验证并返回一个对象。

一种好的做法是像上面的代码那样具有一系列作用域函数吗?

    fun execRequest(endpoint: String, method: String = "GET", body: String? = ""): String =
            defaultHttpRequestBuilder()
                    .uri(URI.create(endpoint))
                    .method(method, HttpRequest.BodyPublishers.ofString(body))
                    .header("Content-Type", "application/x-www-form-urlencoded")
                    .build()
                    .run { httpClient.send(this, HttpResponse.BodyHandlers.ofString()) }
                    .let { it.body() }

    fun processLoginRequest(challenge: String) =
            execRequest(buildEndpoint("login", challenge))
                    .let {
                        mapper.readValue<LoginResponse>(it)
                    }
                    .let {
                        val authSituation = Auth(it.skip, it.challenge)
                        if (it.skip) {
                            val acceptResponse = acceptLoginRequest(challenge, it.subject)
                            authSituation.redirectTo = acceptResponse.redirectTo
                        }
                        authSituation
                    }

我认为这段代码很糟糕。还有另一种以“科特林方式”编写它的方法吗?

1 个答案:

答案 0 :(得分:2)

我认为由于回答只是一个意见问题,这个问题可能会结束,但是既然您问了我的评论,这里就是您如何分解第一个功能的问题。

fun execRequest(endpoint: String, method: String = "GET", body: String? = ""): String {
    val request = defaultHttpRequestBuilder()
        .uri(URI.create(endpoint))
        .method(method, HttpRequest.BodyPublishers.ofString(body))
        .header("Content-Type", "application/x-www-form-urlencoded")
        .build()
    val response = httpClient.send(request, HttpResponse.BodyHandlers.ofString())
    return response.body()
}

我可能会像这样分解第二个功能

fun processLoginRequest(challenge: String): Auth {
    val httpResponse = execRequest(buildEndpoint("login", challenge))
    val loginResponse: LoginResponse = mapper.readValue(httpResponse)
    return Auth(loginResponse.skip, loginResponse.challenge)
        .apply {
            if (loginResponse.skip) 
                redirectTo = acceptLoginRequest(challenge, it.subject).redirectTo
        }
}