Go 避免代码重复

Go 避免代码重复,go,Go,我正在尝试编写一个web应用程序,并努力编写干净的代码 我有一个用于处理传入请求的控制器和所有控制器都将借用字段的基本控制器 这是我的基地控制器 type Controller struct { Request *http.Request Response http.ResponseWriter // Reqeust language lang string // HTML parts Title string body s

我正在尝试编写一个web应用程序,并努力编写干净的代码

我有一个用于处理传入请求的控制器和所有控制器都将借用字段的基本控制器

这是我的基地控制器

type Controller struct {
    Request  *http.Request
    Response http.ResponseWriter

    // Reqeust language
    lang string

    // HTML parts
    Title   string
    body    string
    head    string
    content string
    view    string
    errors  []string
    success []string
}
// And methods followed here
func (self *Controller) renderHeadView() { .....
type Controller struct {
    base.Controller
}

func (self *Controller) ServeHTTP(rw http.ResponseWriter, r *http.Request) {

    self.Title = "Activate account"
    self.Request = r
    self.Response = rw
    self.lang = header.Language(self.Request)

    self.RenderResponseView()
}
func (self *Controller) ServeHTTP(rw http.ResponseWriter, r *http.Request) {

    self.Title = "Activate account"
    self.Request = r
    self.Response = rw
    self.lang = header.Language(self.Request)

    // here would come function for special work
    function()
    self.RenderResponseView()
}
还有我的注册控制器

type Controller struct {
    base.Controller
    user *account
}

func (self *Controller) ServeHTTP(rw http.ResponseWriter, r *http.Request) {

    self.Title = "Sign Up"
    self.Request = r
    self.Response = rw

    self.lang = header.Language(self.Request)
    self.user = &account{lang: self.lang}

    switch self.Request.Method {
    case "GET":
        self.get()
    case "POST":
        if err := self.post(); err != nil {
            self.get()
        } else {
            // If everything was successfully
            return
        }

    }
    self.RenderResponseView()
}
和我的激活控制器

type Controller struct {
    Request  *http.Request
    Response http.ResponseWriter

    // Reqeust language
    lang string

    // HTML parts
    Title   string
    body    string
    head    string
    content string
    view    string
    errors  []string
    success []string
}
// And methods followed here
func (self *Controller) renderHeadView() { .....
type Controller struct {
    base.Controller
}

func (self *Controller) ServeHTTP(rw http.ResponseWriter, r *http.Request) {

    self.Title = "Activate account"
    self.Request = r
    self.Response = rw
    self.lang = header.Language(self.Request)

    self.RenderResponseView()
}
func (self *Controller) ServeHTTP(rw http.ResponseWriter, r *http.Request) {

    self.Title = "Activate account"
    self.Request = r
    self.Response = rw
    self.lang = header.Language(self.Request)

    // here would come function for special work
    function()
    self.RenderResponseView()
}
如您所见,ServeHTTP方法看起来几乎相同。我正在考虑将ServeHTTP移动到base控制器中,然后提供一种方法来调用特殊的工作。为了澄清我的意思,请看下面的代码片段(基本控制器)


我不知道如何提供这种实现。如果有人能给我一些建议,我会很高兴的

一篇好文章是“”

在Go中编写web应用程序时,我们遇到的第一个代码气味是代码重复
在处理请求之前,我们通常需要记录请求、将应用程序错误转换为HTTP 500错误、验证用户等,并且我们需要为每个处理程序执行大部分这些操作

我们可以创建一个带有闭包的函数。但如果我们有多个这样的函数,它将变得像Javascript中的回调意大利面一样糟糕。我们不想那样

因此,我们可以编写一个处理程序并将另一个处理程序传递给它

因此,中间件应该类似于
func(http.Handler)http.Handler

这样,我们传递一个处理程序并返回一个处理程序。最后,我们有一个处理程序,可以使用http.Handle(模式,处理程序)


爱丽丝 。此外,我们可以创建一个通用的处理程序列表,并对每个路由重用它们,如下所示:

问题解决了。我们现在有了一个惯用的中间件系统,它使用标准接口。Alice有50行代码,因此它是一个非常小的依赖项


一篇值得参考的好文章是“”

在Go中编写web应用程序时,我们遇到的第一个代码气味是代码重复
在处理请求之前,我们通常需要记录请求、将应用程序错误转换为HTTP 500错误、验证用户等,并且我们需要为每个处理程序执行大部分这些操作

我们可以创建一个带有闭包的函数。但如果我们有多个这样的函数,它将变得像Javascript中的回调意大利面一样糟糕。我们不想那样

因此,我们可以编写一个处理程序并将另一个处理程序传递给它

因此,中间件应该类似于
func(http.Handler)http.Handler

这样,我们传递一个处理程序并返回一个处理程序。最后,我们有一个处理程序,可以使用http.Handle(模式,处理程序)


爱丽丝 。此外,我们可以创建一个通用的处理程序列表,并对每个路由重用它们,如下所示:

问题解决了。我们现在有了一个惯用的中间件系统,它使用标准接口。Alice有50行代码,因此它是一个非常小的依赖项


我认为您将从查找中间件实现中获益。是一个可以从中学习到很多东西的软件包,尤其是
negroni.go
文件。它有一个非常容易理解的中间件链接机制,您可以在自己的代码中模仿它(或者使用Negroni)。是一个可以从中学习到很多东西的软件包,尤其是
negroni.go
文件。它有一个非常容易理解的中间件链接机制,您可以在自己的代码中进行模拟(或者,只需使用Negroni)。也很重要,以便将值传递给下一个中间件。(同时:)我正在使用negroni作为中间件,但这个场景与middlware纯继承无关。@zero_编码仍然是一个很好的实践,以避免代码重复golang为什么不提供抽象方法?为什么要避免它?@zero_编码,因为golang与继承无关。它是关于作文的。在您的案例中避免代码重复是关于链接中间件(组合),而不是“重用”一个“抽象方法”:在Go中没有继承,想想组合。有关详细信息,请参阅和。也很重要,以便将值传递给下一个中间件。(同时:)我正在使用negroni作为中间件,但这个场景与middlware纯继承无关。@zero_编码仍然是一个很好的实践,以避免代码重复golang为什么不提供抽象方法?为什么要避免它?@zero_编码,因为golang与继承无关。它是关于作文的。在您的案例中避免代码重复是关于链接中间件(组合),而不是“重用”一个“抽象方法”:在Go中没有继承,想想组合。有关详细信息,请参阅和。