Go 中可通过接口+组合+函数字段模拟模板方法模式:定义含 Validate/Process/Notify/LogResult 方法的 PaymentProcessor 接口,Executor 结构体持该接口并实现固定流程 Execute(),具体类型如 CreditCardProcessor 实现接口方法以定制步骤逻辑。
在 Go 语言中,由于没有类继承和抽象方法的原生支持,无法像 Java 或 C++ 那样直接实现传统意义上的模板方法模式(Template Method Pattern),但可以通过 接口 + 组合 + 函数字段 的方式优雅地模拟该模式:定义算法骨架(主流程),将可变步骤延迟到具体类型或函数中实现。
先定义一个接口,描述模板方法要调用的关键步骤。这些方法代表子类需“定制”的细节逻辑:
type PaymentProcessor interface {
Validate() error
Process() error
Notify() error
LogResult(success bool)
}
这个接口不包含主流程(如 Execute()),仅声明钩子步骤——相当于抽象基类中的抽象方法。
创建一个通用执行器结构体,内嵌接口,并提供不可重写的主流程方法:
type Executor struct {
processor PaymentProcessor
}
func (e *Executor) Execute() error {
if err := e.processor.Validate(); err != nil {
e.processor.LogResult(false)
return err
}
if err := e.processor.Process(); err != nil {
e.processor.LogResult(false)
return err
}
if err := e.processor.Notify(); err != nil {
e.processor.LogResult(false)
return err
}
e.processor.LogResult(true)
return nil
}
这就是“模板方法”:流程固定(校验 → 处理 → 通知 → 日志),每步调用接口方法,具体行为由传入的 PaymentProcessor 实现决定。
让具体类型(如 CreditCardProcessor)实现接口,填充细节逻辑:
type CreditCardProcessor struct {
CardNumber string
Amount float64
}
func (c *CreditCardProcessor) Validate() error {
if len(c.CardNumber) < 12 {
return fmt.Errorf("invalid card number")
}
return nil
}
func (c *CreditCardProcessor) Process() error {
fmt.Printf("Charging $%.2f to card %s...\n", c.Amount, c.CardNumber[:4])
return nil // 模拟成功
}
func (c *CreditCardProcessor) Notify() error {
fmt.Println("Sending email receipt...")
return nil
}
func (c *CreditCardProcessor) LogResult(success bool) {
status := "success"
if !success {
status = "failed"
}
fmt.Printf("[Log] Credit card payment %s\n", status)
}
使用时只需组合:
proc := &CreditCardProcessor{
CardNumber: "4532015112830366",
Amount: 99.99,
}
executor := &Executor{processor: proc}
executor.Execute() // 按模板流程运行
若逻辑简单、不想定义完整接口,可用结构体内嵌函数字段,直接注入行为:
type FlexibleExecutor struct {
ValidateFunc func() error
ProcessFunc func() error
NotifyFunc func() error
LogFunc func(success
bool)
}
func (e *FlexibleExecutor) Execute() error {
if err := e.ValidateFunc(); err != nil {
e.LogFunc(false)
return err
}
if err := e.ProcessFunc(); err != nil {
e.LogFunc(false)
return err
}
if err := e.NotifyFunc(); err != nil {
e.LogFunc(false)
return err
}
e.LogFunc(true)
return nil
}
// 使用示例
exec := &FlexibleExecutor{
ValidateFunc: func() error { return nil },
ProcessFunc: func() error { fmt.Println("Processing via API..."); return nil },
NotifyFunc: func() error { fmt.Println("Slack notification sent"); return nil },
LogFunc: func(s bool) { fmt.Printf("Result: %t\n", s) },
}
exec.Execute()
这种方式适合快速原型、测试桩或高度动态的流程定制。
Go 中的模板方法本质是“控制反转”:主流程掌控执行顺序,细节由使用者通过接口实现或函数注入。关键不在语法是否像 OOP,而在是否清晰分离了稳定骨架与易变逻辑——这正是模板方法模式的核心价值。
# java
# go
# golang
# ai
# c++
# red
相关文章:
国美网站制作流程,国美电器蒸汽鍋怎么用官方网站?
香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南
历史网站制作软件,华为如何找回被删除的网站?
制作网站的基本流程,设计网站的软件是什么?
招商网站制作流程,网站招商广告语?
网站按钮制作软件,如何实现网页中按钮的自动点击?
如何在橙子建站上传落地页?操作指南详解
极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?
长沙做网站要多少钱,长沙国安网络怎么样?
如何快速搭建高效简练网站?
陕西网站制作公司有哪些,陕西凌云电器有限公司官网?
广州网站制作公司哪家好一点,广州欧莱雅百库网络科技有限公司官网?
C++时间戳转换成日期时间的步骤和示例代码
建站168自助建站系统:快速模板定制与SEO优化指南
如何规划企业建站流程的关键步骤?
C#如何使用XPathNavigator高效查询XML
广平建站公司哪家专业可靠?如何选择?
在线制作视频的网站有哪些,电脑如何制作视频短片?
建站之星如何实现PC+手机+微信网站五合一建站?
单页制作网站有哪些,朋友给我发了一个单页网站,我应该怎么修改才能把他变成自己的呢,请求高手指点迷津?
如何选择靠谱的建站公司加盟品牌?
焦点电影公司作品,电影焦点结局是什么?
韩国网站服务器搭建指南:VPS选购、域名解析与DNS配置推荐
,在苏州找工作,上哪个网站比较好?
活动邀请函制作网站有哪些,活动邀请函文案?
建站之星如何修改网站生成路径?
建站之星代理费用多少?最新价格详情介绍
深圳 网站制作,深圳招聘网站哪个比较好一点啊?
再谈Python中的字符串与字符编码(推荐)
专业型网站制作公司有哪些,我设计专业的,谁给推荐几个设计师兼职类的网站?
如何基于云服务器快速搭建网站及云盘系统?
购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?
C#如何在一个XML文件中查找并替换文本内容
建站之星代理平台如何选择最佳方案?
如何通过虚拟主机快速完成网站搭建?
猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?
如何用好域名打造高点击率的自主建站?
如何自定义建站之星模板颜色并下载新样式?
建站之星安装需要哪些步骤及注意事项?
ppt制作免费网站有哪些,ppt模板免费下载网站?
MySQL查询结果复制到新表的方法(更新、插入)
子杰智能建站系统|零代码开发与AI生成SEO优化指南
制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?
宝塔新建站点报错如何解决?
东莞市网站制作公司有哪些,东莞找工作用什么网站好?
广州网站建站公司选择指南:建站流程与SEO优化关键词解析
在线教育网站制作平台,山西立德教育官网?
七夕网站制作视频,七夕大促活动怎么报名?
建站与域名管理如何高效结合?
建站之星云端配置指南:模板选择与SEO优化一键生成
*请认真填写需求信息,我们会在24小时内与您取得联系。