Golang 设计模式-装饰模式

简单装饰器

我们通过一个简单的例子来看一下装饰器的简单应用,首先编写一个 hello 函数:

package main

import "fmt"

func hello() {
    fmt.Println("Hello World!")
}

func main() {
    hello()
}

完成上面代码后,执行会输出“Hello World!”。接下来通过以下方式,在打印“Hello World!”前后各加一行日志:

package main

import "fmt"

func hello() {
    fmt.Println("before")
    fmt.Println("Hello World!")
    fmt.Println("after")
}

func main() {
    hello()
}

代码执行后输出:

`before
Hello World!
after`
当然我们可以选择一个更好的实现方式,即单独编写一个专门用来打印日志的 logger 函数,示例如下:

package main

import "fmt"

func logger(f func()) func() {
    return func() {
        fmt.Println("before")
        f()
        fmt.Println("after")
    }
}

func hello() {
    fmt.Println("Hello World!")
}

func main() {
    hello := logger(hello)
    hello()
}

可以看到 logger 函数接收并返回了一个函数,且参数和返回值的函数签名同 hello 一样。然后我们在原来调用 hello() 的位置进行如下修改:

`hello := logger(hello)
hello()`
这样我们通过 logger 函数对 hello 函数的包装,更加优雅的实现了给 hello 函数增加日志的功能。执行后的打印结果仍为:

`before
Hello World!
after`
其实 logger 函数也就是我们在 Python 中经常使用的装饰器,因为 logger 函数不仅可以用于 hello,还可以用于其他任何与 hello 函数有着同样签名的函数。

当然如果想使用 Python 中装饰器的写法,我们可以这样做:

package main

import "fmt"

func logger(f func()) func() {
    return func() {
        fmt.Println("before")
        f()
        fmt.Println("after")
    }
}

// 给 hello 函数打上 logger 装饰器

@logger
func hello() {
    fmt.Println("Hello World!")
}

func main() {
    // hello 函数调用方式不变
    hello()
}

但很遗憾,上面的程序无法通过编译。因为 Go 语言目前还没有像 Python 语言一样从语法层面提供对装饰器语法糖的支持。

你可能感兴趣的:(golang)