适合流程固定,有些步骤有特殊实现的情况。类图如下。优缺点不分析了,直接上实现

go
package main
import (
"fmt"
)
// Template 接口
type Template interface {
TemplateMethod(template Template)
// 钩子方法,需要子类去具体的实现
step1Func()
exposedFunc()
step3Func()
}
// BaseTemplate 基础模板,编排方法,提供复用的方法
type BaseTemplate struct {
}
// NewBaseTemplate 创建基础模板
func NewBaseTemplate() *BaseTemplate {
return &BaseTemplate{}
}
// TemplateMethod 模板方法
func (b *BaseTemplate) TemplateMethod(template Template) {
fmt.Println("=== 开始执行模板方法 ===")
if template == nil {
return
}
template.step1Func()
template.exposedFunc()
template.step3Func()
fmt.Println("=== 模板方法执行完成 ===")
}
// 基础方法1:子类可以不实现
func (b *BaseTemplate) step1Func() {
fmt.Println("=== base.step1Func is called ===")
}
// 钩子方法,子类必须实现
func (b *BaseTemplate) exposedFunc() {
panic("exposed Func must be implement!")
}
// 基础方法2:子类可以直接继承基类的,可以不实现
func (b *BaseTemplate) step3Func() {
fmt.Println("=== base.step3Func is called ===")
}
// ==================== 具体实现 ====================
// ConcreteTemplateA
type ConcreteTemplateA struct {
*BaseTemplate
}
func NewConcreteTemplateA() *ConcreteTemplateA {
base := NewBaseTemplate()
c := &ConcreteTemplateA{BaseTemplate: base}
return c
}
func (c *ConcreteTemplateA) exposedFunc() {
fmt.Println("具体模板A: exposedFunc - 特殊实现")
}
// ConcreteTemplateB
type ConcreteTemplateB struct {
*BaseTemplate
}
func NewConcreteTemplateB() *ConcreteTemplateB {
base := NewBaseTemplate()
c := &ConcreteTemplateB{BaseTemplate: base}
return c
}
func (c *ConcreteTemplateB) step1Func() {
fmt.Println("具体模板B:step1Func override")
}
func (c *ConcreteTemplateB) exposedFunc() {
fmt.Println("具体模板B: exposedFunc -- 钩子函数实现")
}
// ==================== 使用示例 ====================
func InitTemplate(templateKey string) Template {
// 路由判断使用哪套模板
mp := make(map[string]Template)
mp["templateA"] = NewConcreteTemplateA()
mp["templateB"] = NewConcreteTemplateA()
if ans, exist := mp[templateKey]; exist {
return ans
}
panic(fmt.Sprintf("There is no template named %s", templateKey))
}
func main() {
templateA := InitTemplate("templateA")
templateB := InitTemplate("templateB")
var baseTemplate Template = NewBaseTemplate() // 可以不要
fmt.Println("=== 模板A执行 ===")
baseTemplate.TemplateMethod(templateA)
fmt.Println("\n=== 模板B执行 ===")
baseTemplate.TemplateMethod(templateB)
}
