Go语言通过函数式编程和接口组合实现装饰器模式,可动态添加日志、缓存等功能而不修改原对象。1. 使用高阶函数包装处理逻辑,如WithLogging记录调用前后信息;2. 通过接口与嵌入结构体实现对象装饰,如CachedReader为Reader添加缓存;3. 支持链式装饰,按顺序组合多个增强行为,如日志+重试;4. 借助类型系统和组合思想,以包装与委托为核心,灵活构建可复用、可扩展的装饰逻辑。

在Go语言中,虽然没有像Python那样的@decorator语法糖,但通过函数式编程和接口组合,可以自然地实现装饰器模式。这种模式允许你在不修改原始对象的前提下,动态地给对象添加新功能,非常适合日志、权限校验、缓存、监控等横切关注点。
当你的核心逻辑是函数时,可以通过高阶函数的方式实现装饰。例如,一个处理HTTP请求的函数,你可以用装饰器包裹它,实现统一的日志记录或耗时统计。
定义一个处理函数类型:
type HandlerFunc func(string) string编写一个日志装饰器:
立即学习“go语言免费学习笔记(深入)”;
func WithLogging(fn HandlerFunc) HandlerFunc { return func(s string) string { fmt.Printf("调用前: 输入=%s\n", s) result := fn(s) fmt.Printf("调用后: 输出=%s\n", result) return result } }使用方式如下:
handler := func(s string) string { return "Hello " + s } loggedHandler := WithLogging(handler) loggedHandler("Alice") // 自动打印日志对于更复杂的对象行为扩展,可以结合接口和嵌入结构体来模拟装饰器。比如你有一个数据读取器接口:
type Reader interface { Read() string }基础实现:
type FileReader struct{} func (f *FileReader) Read() string { return "从文件读取数据" }现在你想添加缓存功能,又不想改动原有代码,就可以写一个缓存装饰器:
type CachedReader struct { reader Reader cache string cached bool } func (c *CachedReader) Read() string { if !c.cached { c.cache = c.reader.Read() c.cached = true fmt.Println("实际读取并缓存") } else { fmt.Println("命中缓存") } return c.cache }使用时只需包装原对象:
fileReader := &FileReader{} cachedReader := &CachedReader{reader: fileReader} cachedReader.Read() // 实际读取 cachedReader.Read() // 命中缓存Go的优势在于你可以将多个装饰器串联起来,形成处理链。比如同时加上日志和重试:
func WithRetry(reader Reader, retries int) Reader { return &RetryReader{reader: reader, retries: retries} } // 包装顺序决定执行顺序 reader := &FileReader{} decorated := WithLogging(WithRetry(reader, 3))调用 decorated.Read() 会先走日志逻辑,再进入重试机制,最后执行真实读取。这种组合方式清晰且可复用。
基本上就这些。Go的装饰器不像其他语言那样“显眼”,但它依靠类型系统和组合哲学,反而更灵活、更贴近实际工程需求。关键在于理解“行为增强”本质是包装与委托,而不是依赖特定语法。只要掌握函数封装和接口抽象,就能自然写出符合场景的装饰逻辑。
以上就是Golang如何实现装饰器模式添加功能_Golang Decorator模式扩展技巧的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号