如何重构重复的是,有一个参数在Groovy方法调用倒闭?(How to refactor dupli

2019-10-20 11:28发布

考虑这个现实世界的例子,这是编写的代码,使“GET”和“POST”呼吁通过REST客户端生成器(Grails的插件)相同REST服务端点。 我不喜欢在标题和内容类型设置为相同的重复,但我不知道如何重构普通片出来给他们正在呼叫正在传递给GET)在封闭的方法(或post()方法调用。 请提供一个良好的重构的一个具体的例子出来在你的答案重复的。

   private def doGetCall(String endpoint, def config) {
       def response = new RestBuilder().get(config.baseURI+endpoint) {
           contentType("application/json")
           header("Authorization", "ApiKey " + config.base64EncodedApiKey)
           header("ClientId", config.clientId)
       }

       handleResponse(response, config, endpoint);
       return response;
   }

   private def doPostCall(String endpoint, def payload, def config) {
       def response = new RestBuilder().post(config.baseURI+endpoint) {
           contentType("application/json")
           header("Authorization", "ApiKey " + config.base64EncodedApiKey)
           header("ClientId", config.clientId)
           json(payload)
       }

       handleResponse(response, config, endpoint, payload)
       return response;
   }

Answer 1:

Groovy的1.8封添加成分,因此,如果您使用的是版本的Grails的,它使用Groovy的1.8或更高版本:

private def doGetCall(String endpoint, def config) {
    def response = new RestBuilder().get(config.baseURI+endpoint, composeRequest(config))

    handleResponse(response, config, endpoint);
    return response;
}

private def doPostCall(String endpoint, def payload, def config) {
    def response = new RestBuilder().post(config.baseURI+endpoint, composeRequest(config, { json(payload) }))

    handleResponse(response, config, endpoint, payload)
    return response;
}

private def composeRequest(def config, Closure clos = null) {
    def request = {
        contentType("application/json")
        header("Authorization", "ApiKey " + config.base64EncodedApiKey)
        header("ClientId", config.clientId)
    }
    if (clos != null) {
        request = request << clos
    }
    request
}


Answer 2:

这是否会足够?

class RestTestService {
    def rest

    def methodMissing(String name, args) {
        if( !( name in ['get', 'post'] ) ) { // can add PUT & DELETE in future
            // throw missing method exception for method names other than above
            throw new MissingMethodException(
               "Http Method $name does not exist or not yet implemented.") 
        }

        def (endpoint, config, payload) = args?.toList()

        def response = rest."$name"(config.baseURI + endpoint) {
            contentType( "application/json" )
            header("Authorization", "ApiKey " + config.base64EncodedApiKey )
            header( "ClientId", config.clientId )
            if ( name == 'post' && payload ) {
                json( payload )
            }
        }

        handleResponse(response, config, endpoint)

        return response
    }

    private void handleResponse(def response, def config, def endpoint) { ... }

    public def doGetCall(String endpoint, def config) {
        get( endpoint, config )
    }

    public def doPostCall(String endpoint, def payload, def config) {
        post( endpoint, config, payload )
    }
}

//resources.groovy
beans = {
    rest(grails.plugins.rest.client.RestBuilder)
}

上述利用的methodMissing ,以决定在运行时调用哪个HTTP方法。
还要注意,而不是创造, RestBuilder每个HTTP调用,我建议把它作为一个bean如上所示resources.groovy并在使用时它注入到类。 如果它是一个Grails神器(控制器,服务),那么它就会自动连接,否则豆rest必须适当接线。 您可以通过使用抽象doGetCalldoPostCall或完全如果需要删除它们。



文章来源: How to refactor duplication out of closures that are an argument to a method call in Groovy?