去解决重复代码的解决方案(延迟,net / http)

时间:2014-09-29 08:33:32

标签: go

我在Go中有以下代码:

func (api *ApiResource) create(request *restful.Request, response *restful.Response) {
    account := &DefaultAccount
    err := request.ReadEntity(account)
    if err != nil {
        response.WriteErrorString(http.StatusInternalServerError, err.Error())
        return
    }
    tmpl := data_transformer.ParseTemplate("xml/accAdd.xml")
    payload := data_transformer.RenderTemplate(tmpl, account)
    resp, err := http.Post(url, "application/xml", payload)
    if err != nil {
        response.WriteErrorString(http.StatusInternalServerError, err.Error())
        return
    }

    // Body closes when either at the end of the function or at return
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)

    aResp := new(AResp)
    err = xml.Unmarshal(body, aResp)
    if err != nil {
        fmt.Printf("error: %v", err)
        return
    }
    response.WriteHeader(http.StatusCreated)
    response.WriteEntity(aResp)
}

func (api *ApiResource) updateLimit(request *restful.Request, response *restful.Response) {
    account := &DefaultLimit
    err := request.ReadEntity(account)
    if err != nil {
        response.WriteErrorString(http.StatusInternalServerError, err.Error())
        return
    }
    tmpl := data_transformer.ParseTemplate("xml/addLimit.xml")
    payload := data_transformer.RenderTemplate(tmpl, account)
    resp, err := http.Post(url, "application/xml", payload)
    if err != nil {
        response.WriteErrorString(http.StatusInternalServerError, err.Error())
        return
    }

    // Body closes when either at the end of the function or at return
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)

    aResp := new(AResp)
    err = xml.Unmarshal(body, aResp)
    if err != nil {
        fmt.Printf("error: %v", err)
        return
    }
    response.WriteHeader(http.StatusCreated)
    response.WriteEntity(aResp)
}

我希望能够以优雅的方式删除重复的代码Go style。

如果我删除它们并将它们放在单独的函数中,是否所有defer和net / http包都按预期工作,以用于不同的调用和xml文件加载?

什么是优秀的Go类型解决方案?

1 个答案:

答案 0 :(得分:1)

您几乎可以分离整个功能,只需将“帐户”和xml文件传递给它即可。

从流中读取时,使用xml.Decoder代替xml.Unmarshal也是一种更好的做法。

func updateEntity(response *restful.Response, fn string, iface interface{}) {
    tmpl := data_transformer.ParseTemplate("xml/" + fn)
    payload := data_transformer.RenderTemplate(tmpl, iface)
    resp, err := http.Post(url, "application/xml", payload)
    if err != nil {
        response.WriteErrorString(http.StatusInternalServerError, err.Error())
        return
    }

    defer resp.Body.Close()
    dec := xml.NewDecoder(resp.Body)
    body, err := ioutil.ReadAll(resp.Body)

    aResp := &AResp{}
    err = dec.Decode(aResp)
    if err != nil {
        fmt.Printf("error: %v", err)
        return
    }
    response.WriteHeader(http.StatusCreated)
    response.WriteEntity(aResp)
}

func (*ApiResource) create(request *restful.Request, response *restful.Response) {
    account := &DefaultAccount
    err := request.ReadEntity(account)
    if err != nil {
        response.WriteErrorString(http.StatusInternalServerError, err.Error())
        return
    }
    updateEntity(response, "accAdd.xml", account)
}
func (*ApiResource) updateLimit(request *restful.Request, response *restful.Response) {
    account := &DefaultLimit
    err := request.ReadEntity(account)
    if err != nil {
        response.WriteErrorString(http.StatusInternalServerError, err.Error())
        return
    }
    updateEntity(response, "addLimit.xml", account)
}