仅传递一次接口的方法参数?

时间:2018-06-09 13:50:06

标签: go

我试图通过在父结构中只调用一次接口方法的参数来设法让我的代码更简单,更简单(?)

首先定义路线:

func Init() {
    // Create route
    r := mux.NewRouter()

    // Default routes
    router.Route("/", webtest.TestController{}, r)

    // Serve the routes
    router.Serve(r)
}

然后是它的功能:

type Controller struct {
    ControllerInterface
}

type ControllerInterface interface {
    Get(w http.ResponseWriter, r *http.Request)
}

func Route(path string, ct interface{}, r *mux.Router) {
    if c, ok := ct.(controllers.ControllerInterface); ok {
        r.HandleFunc(path, http.HandlerFunc(c.Get)).Methods("GET")
    }
}

然后我用

打电话给路线
type TestController struct {
    controllers.Controller
}

func (c TestController) Get(w http.ResponseWriter, r *http.Request) {
    println("Hello World")
}

正如您所看到的,我必须到处都有w http.ResponseWriter, r *http.Request,否则路线将无效。有没有什么办法可以在父结构(或类似的)中包含这些参数,所以我不必每次都包含它?

2 个答案:

答案 0 :(得分:0)

只需将您在Init中调用的位移动到主函数中即可。在启动时调用Init,当Init退出时,在其中创建的任何内容都可能消失。

func main(){
    r := mux.NewRouter()

    // Default routes
    router.Route("/", webtest.TestController{}, r)

    // Serve the routes
    router.Serve(r)
}

答案 1 :(得分:0)

不幸的是,我认为不会有一个你满意的答案。在一天结束时,必须满足以下条件:

每个处理程序必须使用http.Responsewriter*http.Request来处理请求。

要记住的一点是,更短更简单并不总是齐头并进。将编写器和响应传递给需要它们的函数虽然略显冗长,但却非常简单。

让您最开心的是将大部分逻辑实际上推到一些处理操作语义而不是网络请求层的其他方法中。使用GET请求加载记录作为示例,您可以将其构造为:

func main() {
    http.DefaultServeMux.HandleFunc("/", getHandler)

    if err := http.ListenAndServe(":8080", nil); err != nil {
        panic(err)
    }
}

func getHandler(w http.ResponseWriter, r *http.Request) {
    // Do stuff with the request, like deserialize
    // Extract the ID
    // Call getLogic
    // return an appropriate error or serialize the response back out
}

func getLogic(recordID int) (Record, error) {
    // Do actual interesting logic here.
}

像这样拆分并不是没有简单的潜在成本。虽然它确实允许您测试逻辑块而无需处理http.ResponseWriterhttp.Request,但您现在必须决定切割该接缝的位置。这样做可能会很尴尬。

您也可以尝试采用不同的方法,例如按请求创建结构,将编写器和请求放在其上,然后调用适当的方法,但我不推荐它:

func getHandler(w http.ResponseWriter, r *http.Request) {
    SingleRequest{w, r}.Get()
}

type SingleRequest struct {
    writer  http.ResponseWriter
    request *http.Request
}

func (s SingleRequest) Get() {
    // Do logic here, but the method still has to access s.writer and s.request
}

这两种方法都没有提供简洁的简洁性。在我看来,它们产生的少量简洁是以简单为代价的。然而,第一种方法可能是合理的,这取决于给定处理程序的复杂性。毕竟,它是扩展较小功能的模式,以打破更大的功能。

目前,我不知道任何在减少代码大小的同时普遍增加简单性的方法。相反,我们应该关注为什么你觉得这是一个需要首先解决的问题。您熟悉标准库中的httptest包吗?如果您关心测试,它将帮助您测试这些处理程序。