在Golang中并没有像Python那样直接的装饰器语法,但我们可以通过接口和结构体嵌套来实现装饰器模式,从而在不修改原有代码的情况下动态扩展对象功能。这种模式在日常开发中非常适合添加日志、监控、缓存等横切逻辑。

什么是装饰器模式
装饰器模式的核心思想是:定义一个基础接口,让原始对象和装饰器都实现这个接口。装饰器内部持有一个被装饰的接口实例,在调用方法前后加入自己的逻辑,再把请求转发出去。这样多个装饰器可以一层层包起来,功能就动态叠加了。
定义通用接口与基础实现
下面以一个简单的文本处理器为例,先定义接口和原始实现:
package main
import "fmt"
// 定义组件接口
type TextProcessor interface {
Process(input string) string
}
// 基础实现:转为大写
type UpperProcessor struct{}
func (u *UpperProcessor) Process(input string) string {
result := ""
for _, c := range input {
if c >= 'a' && c <= 'z' {
result += string(c - 32)
} else {
result += string(c)
}
}
return result
}
func main() {
var p TextProcessor = &UpperProcessor{}
fmt.Println(p.Process("hello"))
}
实现装饰器
我们创建两个装饰器,一个加前缀,一个记录日志。它们都实现了TextProcessor接口,并持有被装饰对象。
package main
import "fmt"
// 日志装饰器
type LogDecorator struct {
processor TextProcessor
}
func (l *LogDecorator) Process(input string) string {
fmt.Println("调用前输入:", input)
out := l.processor.Process(input)
fmt.Println("调用后输出:", out)
return out
}
// 前缀装饰器
type PrefixDecorator struct {
processor TextProcessor
prefix string
}
func (p *PrefixDecorator) Process(input string) string {
return p.prefix + p.processor.Process(input)
}
动态组合装饰器
在main函数中,我们可以按需要把装饰器嵌套起来,实现功能的动态扩展:
func main() {
base := &UpperProcessor{}
withLog := &LogDecorator{processor: base}
withPrefix := &PrefixDecorator{processor: withLog, prefix: ">> "}
// 动态扩展后的对象
var p TextProcessor = withPrefix
result := p.Process("hello")
fmt.Println("最终结果:", result)
}
使用建议
- 当功能组合较多且易变时,装饰器比写很多结构体嵌入更清晰。
- 注意装饰器层数过多会影响可读性和调试难度。
- 如果扩展逻辑非常通用,也可考虑Go的中间件或函数包装写法。
装饰器模式让Golang中的对象功能扩展保持开放封闭原则,是写出易维护代码的有效手段。