信息发布→ 登录 注册 退出

如何使用Golang实现模板方法模式_使用Template Method控制执行流程

发布时间:2026-01-02

点击量:
模板方法模式在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 继承,而是靠接口契约 + 函数注入 + 结构体组合来达成同样的目的——流程统一、扩展自由、耦合更低。

标签:# 算法  # 可选  # 就把  # 可以通过  # 设为  # 这一  # 进阶  # 自己的  # 更低  # 只需  # http  # 数据库  # go  # nil  # class  # 接口  # 继承  # 结构体  # 子类  # 封装  # sql  # ai  # 处理器  # golang  
在线客服
服务热线

服务热线

4008888355

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!