doushi9444 2014-09-20 09:15
浏览 1
已采纳

简化Go代码

I have two functions as shown below which look similar, but using different functions to query the db. Since Go doesn't encourage overloaading methods, is the redundancy acceptable? Or should I refactor them into one function? All comments are welcomed.

var getCustomers = func() ([]customer, error) {
    return nil, nil
}

var getCustomerById = func(int64) (*customer, error) {
    return nil, nil
}

func listCustomer(w http.ResponseWriter, r *http.Request) *appError {
    cus, err := getCustomers()
    if err != nil {
        return &appError{err, "No customer found", 404}
    }

    res, err := json.Marshal(cus)

    if err != nil {
        return &appError{err, "Can't display record", 500}
    }

    fmt.Fprint(w, string(res))
    return nil
}

func viewCustomer(w http.ResponseWriter, r *http.Request, id int64) *appError {
    cus, err := getCustomerByID(id)
    if err != nil {
        return &appError{err, "No customer found", 404}
    }

    res, err := json.Marshal(cus)

    if err != nil {
        return &appError{err, "Can't display record", 500}
    }

    fmt.Fprint(w, string(res))
    return nil
}

Suggestion to use -1 to list all customer, but I'm not sure if this is the best it can be:

func viewCustomer(w http.ResponseWriter, r *http.Request, id int64) *appError {
    var c *customer
    var clist []customer
    var err error

    if id < 0 {
        clist, err = getCustomers()
        res, err := json.Marshal(clist)

        if err != nil {
            return &appError{err, "Can't display record", 500}
        }

        fmt.Fprint(w, string(res))
        return nil
    } else {
        c, err = getCustomerById(id)
        res, err := json.Marshal(c)

        if err != nil {
            return &appError{err, "Can't display record", 500}
        }

        fmt.Fprint(w, string(res))
        return nil
    }
}
  • 写回答

1条回答 默认 最新

  • dtd14883 2014-09-20 09:52
    关注

    Since Go doesn't encourage overloaading methods, is the redundancy acceptable? Or should I refactor them into one function?

    The answer to your question depends heavily on the real code and your task. If listing one customer is very different from listing several customers (that is, you need different information and have different presentation logic), I'd say that duplication here is not that bad, since the difference may grow larger in the future, so a DRY solution could turn into an if and switch mess quickly. (I've had a similar experience on a non-Go project and since then I think that DRY is good but you should not be fanatic about it.)

    On the other hand, if you're making, say a JSON API, you could make it more DRY. Define your getCustomers function like this:

    func customers(ids ...int64) ([]customer, error) { /* ... */ }
    

    This way you can:

    • call it like customers() and get all customers;
    • call customers(42) and get a customer whose ID is 42;
    • call customers(someIDs...) and get multiple customers by their IDs.

    All can be done in one handler in a straightforward way.

    All comments are welcomed.

    Two nitpicks on your code:

    • Getter methods in Go are idiomatically named foo and not getFoo, so I used customers in my example. You would most probably call it as DB.Customers(ids...), so it looks a lot like a getter method.

    • What's up with var foo = func() notation? Unless there is a reason for that (like using these functions as closures), I'd suggest sticking with the func foo() notation, since it's more idiomatic and generally easier to grep. EDIT: as OP pointed out in the comments, another case for var foo = func() notation is of course functions that can be faked in testing, as shown in Andrew Gerrand's Testing Techniques talk.

    I hope that helps.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 想问一下树莓派接上显示屏后出现如图所示画面,是什么问题导致的
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号