go语言设计模式<一>模板方法

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

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)
}
相关推荐
喜欢喝果茶.16 小时前
QOverload<参数列表>::of(&函数名)信号槽
开发语言·qt
亓才孓16 小时前
[Class类的应用]反射的理解
开发语言·python
努力学编程呀(๑•ี_เ•ี๑)16 小时前
【在 IntelliJ IDEA 中切换项目 JDK 版本】
java·开发语言·intellij-idea
feasibility.16 小时前
AI 编程助手进阶指南:从 Claude Code 到 OpenCode 的工程化经验总结
人工智能·经验分享·设计模式·自动化·agi·skills·opencode
island131417 小时前
CANN GE(图引擎)深度解析:计算图优化管线、内存静态规划与异构任务的 Stream 调度机制
开发语言·人工智能·深度学习·神经网络
坚持就完事了17 小时前
Java中的集合
java·开发语言
BD_Marathon17 小时前
七大设计原则介绍
设计模式
魔芋红茶17 小时前
Python 项目版本控制
开发语言·python
云小逸17 小时前
【nmap源码解析】Nmap OS识别核心模块深度解析:osscan2.cc源码剖析(1)
开发语言·网络·学习·nmap
冰暮流星17 小时前
javascript之二重循环练习
开发语言·javascript·数据库