模板方法模式在Go中通过接口定义算法骨架、结构体封装通用流程、函数字段注入具体行为来实现。BaseProcessor统一调度Setup→DoWork→Cleanup,各业务只需组合并设置对应函数即可定制,无需继承,耦合更低。

模板方法模式的核心是:定义一个算法的骨架,将某些步骤延迟到子类中实现,让子类在不改变算法结构的前提下重新定义该算法的某些特定步骤。Golang 没有继承机制,但可以通过组合 + 接口 + 函数字段优雅地实现这一模式。
用接口定义“算法骨架”
先定义一个接口,声明模板方法(即主流程)和可被定制的钩子方法:
type Processor interface {
// 模板方法:固定执行顺序
Execute()
// 钩子方法:由具体实现决定
Setup() error
DoWork() error
Cleanup() error
}
这个接口不强制实现细节,只约定流程节点——Setup → DoWork → Cleanup,而 Execute 是统一调度者。
用结构体封装通用流程逻辑
定义一个基础结构体,内嵌接口字段或直接聚合行为函数,实现可复用的 Execute:
立即学习“go语言免费学习笔记(深入)”;
type BaseProcessor struct {
setupFunc func() error
doWorkFunc func() error
cleanupFunc func() error
}
func (bp *BaseProcessor) Execute() {
if bp.setupFunc != nil {
if err := bp.setupFunc(); err != nil {
log.Printf("setup failed: %v", err)
return
}
}
if bp.doWorkFunc != nil {
if err := bp.doWorkFunc(); err != nil {
log.Printf("work failed: %v", err)
return
}
}
if bp.cleanupFunc != nil {
bp.cleanupFunc() // cleanup 通常不中断流程,即使出错也继续
}
}
这样就把“流程控制权”收归 BaseProcessor,各业务只需注入自己的函数即可定制行为。
按需创建具体处理器
无需继承,只需组合 BaseProcessor 并设置对应函数:
- 文件处理器:打开文件 → 读取内容 → 关闭文件
- HTTP 请求器:初始化 client → 发起请求 → 关闭连接(如需)
- 数据库任务:开启事务 → 执行 SQL → 提交/回滚
示例:
fileProc := &BaseProcessor{
setupFunc: func() error {
fmt.Println("Opening file...")
return nil
},
doWorkFunc: func() error {
fmt.Println("Processing file data...")
return nil
},
cleanupFunc: func() {
fmt.Println("Closing file...")
},
}
fileProc.Execute()
进阶:支持钩子开关与默认行为
可为钩子添加是否启用的标记,或提供默认空实现,增强灵活性:
type ConfigurableProcessor struct {
enableSetup, enableCleanup bool
setupFunc, doWorkFunc, cleanupFunc func() error
}
func (cp *ConfigurableProcessor) Execute() {
if cp.enableSetup && cp.setupFunc != nil {
cp.setupFunc()
}
cp.doWorkFunc()
if cp.enableCleanup && cp.cleanupFunc != nil {
cp.cleanupFunc()
}
}
也可以把 setupFunc 等设为可选字段,nil 时跳过,避免每次都判空。
基本上就这些。Golang 的模板方法不靠 class 继承,而是靠接口契约 + 函数注入 + 结构体组合来达成同样的目的——流程统一、扩展自由、耦合更低。










