跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
Go 装饰器模式
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
= Go装饰器模式 = '''装饰器模式'''(Decorator Pattern)是一种结构型设计模式,允许在不修改原有对象的情况下动态地扩展其功能。在Go语言中,由于缺乏类继承机制,装饰器模式通常通过组合和接口来实现。它特别适用于需要为对象添加额外行为而又不改变其结构的场景。 == 基本概念 == 装饰器模式的核心思想是: * 定义一个基础接口,表示被装饰对象的类型。 * 创建具体的实现类,实现基础接口。 * 创建装饰器结构体,同样实现基础接口,并包含一个基础接口类型的成员变量。 * 在装饰器的方法中,调用成员变量的方法,并在其前后添加额外的行为。 数学上可以表示为:若原始函数为<math>f(x)</math>,装饰后的函数为<math>g(f(x))</math>,其中<math>g</math>是装饰逻辑。 == Go实现示例 == 以下是一个简单的Go装饰器示例,展示如何为函数添加日志功能: <syntaxhighlight lang="go"> package main import ( "fmt" "time" ) // 基础接口 type Worker interface { DoWork() string } // 具体实现 type BasicWorker struct{} func (b *BasicWorker) DoWork() string { return "Basic work done" } // 日志装饰器 type LoggingDecorator struct { worker Worker } func (l *LoggingDecorator) DoWork() string { start := time.Now() result := l.worker.DoWork() end := time.Now() fmt.Printf("Work started at: %v\n", start) fmt.Printf("Work result: %s\n", result) fmt.Printf("Work ended at: %v\n", end) fmt.Printf("Duration: %v\n", end.Sub(start)) return result } func main() { basic := &BasicWorker{} decorated := &LoggingDecorator{worker: basic} fmt.Println("Basic worker:") fmt.Println(basic.DoWork()) fmt.Println("\nDecorated worker:") decorated.DoWork() } </syntaxhighlight> '''输出结果:''' <pre> Basic worker: Basic work done Decorated worker: Work started at: 2023-05-15 10:30:00.123456 +0800 CST m=+0.000000001 Work result: Basic work done Work ended at: 2023-05-15 10:30:00.123457 +0800 CST m=+0.000000002 Duration: 1ns </pre> == 装饰器链 == 可以创建多个装饰器并将它们链接起来,每个装饰器添加不同的功能: <syntaxhighlight lang="go"> // 计时装饰器 type TimingDecorator struct { worker Worker } func (t *TimingDecorator) DoWork() string { start := time.Now() result := t.worker.DoWork() fmt.Printf("Operation took: %v\n", time.Since(start)) return result } func main() { basic := &BasicWorker{} decorated := &TimingDecorator{ worker: &LoggingDecorator{worker: basic}, } decorated.DoWork() } </syntaxhighlight> == 函数装饰器 == 在Go中,函数是一等公民,可以直接装饰函数: <syntaxhighlight lang="go"> type WorkerFunc func() string func Logging(f WorkerFunc) WorkerFunc { return func() string { fmt.Println("Before execution") result := f() fmt.Println("After execution") return result } } func main() { basic := func() string { return "Basic function work" } decorated := Logging(basic) fmt.Println(decorated()) } </syntaxhighlight> == 实际应用场景 == 1. '''日志记录''':在不修改业务逻辑的情况下添加日志 2. '''性能监控''':测量函数执行时间 3. '''缓存''':为昂贵操作添加缓存层 4. '''认证/授权''':在执行业务逻辑前检查权限 5. '''重试机制''':为可能失败的操作添加自动重试 === HTTP中间件案例 === HTTP中间件是装饰器模式的典型应用: <syntaxhighlight lang="go"> package main import ( "fmt" "net/http" ) type Handler func(http.ResponseWriter, *http.Request) func LoggingMiddleware(next Handler) Handler { return func(w http.ResponseWriter, r *http.Request) { fmt.Printf("Request: %s %s\n", r.Method, r.URL.Path) next(w, r) } } func AuthMiddleware(next Handler) Handler { return func(w http.ResponseWriter, r *http.Request) { if r.Header.Get("Authorization") == "" { http.Error(w, "Unauthorized", http.StatusUnauthorized) return } next(w, r) } } func mainHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "Main handler executed") } func main() { handler := LoggingMiddleware(AuthMiddleware(mainHandler)) http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil) } </syntaxhighlight> == 类图表示 == <mermaid> classDiagram class Worker { <<interface>> DoWork() string } class BasicWorker { DoWork() string } class LoggingDecorator { -worker Worker DoWork() string } class TimingDecorator { -worker Worker DoWork() string } Worker <|-- BasicWorker Worker <|-- LoggingDecorator Worker <|-- TimingDecorator LoggingDecorator o-- Worker TimingDecorator o-- Worker </mermaid> == 优缺点 == '''优点:''' * 比继承更灵活,可以在运行时添加或移除功能 * 符合开闭原则,无需修改现有代码就能扩展功能 * 可以组合多个装饰器实现复杂功能 '''缺点:''' * 可能引入许多小类,增加系统复杂度 * 装饰器栈过深可能影响性能 * 调试可能变得困难,因为行为分布在多个装饰器中 == 总结 == Go装饰器模式提供了一种强大的方式来扩展对象功能而不修改其结构。通过组合和接口,Go开发者可以实现类似其他语言中通过继承获得的功能扩展。这种模式特别适合需要动态添加功能的场景,如中间件、日志、监控等。理解装饰器模式有助于编写更灵活、可维护的Go代码。 [[Category:编程语言]] [[Category:Go]] [[Category:Go 函数式编程]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)