《golang设计模式》第三部分·行为型模式-10-模板方法(Template Method)

文章目录

  • [1. 概述](#1. 概述)
    • [1.1 角色](#1.1 角色)
    • [1.2 类图](#1.2 类图)
  • [2. 代码示例](#2. 代码示例)
    • [2.1 设计](#2.1 设计)
    • [2.2 代码](#2.2 代码)
    • [2.3 类图](#2.3 类图)

1. 概述

模板方法(Template Method)用来定义算法的框架,将算法中的可变步骤定义为抽象方法,指定子类实现或重写。

1.1 角色

  • AbstractClass(抽象类):用来定义算法框架和抽象操作
    • templateMethod()方法:使用final修饰,包含了不可变的算法,不允许子类重定义它。
    • invariantStep()方法,可见性为privat,子类不可见,也不能重定义。
    • variantStep():可见性是protected,允许子类继承和重定义。
  • ConcreteClass(具体实现类):用来实现算法框架中的某些步骤,完成与特定子类相关的功能

1.2 类图

AbstractClass +templateMethod() -invariantStep() #variantStep() ConcreteClass #variantStep()

2. 代码示例

2.1 设计

  • 定义抽象类AbstractClass
    • 定义templateMethod()方法,包含了不可变的算法
    • 定义variantStep()方法,是可以被子类重写的方法
    • 定义invariantStep()方法,是抽象类的私有方法
      • 它应该是子类不可见的,但是go中无法真正实现,我们可以把它放到templateMethod()方法中执行,已达到子类视而不见的效果。
  • 定义具体实现类ConcreteClass
    • 它继承了抽象类AbstractClass
    • 它的方法variantStep()重写了父类的variantStep()方法
    • 它的Execute()是它的执行方法
  • 调用
    • 实例化抽象类abstractClass
    • 实例化具体实现类concreteClass,继承了抽象类abstractClass
    • 执行concreteClassExecute()方法
      • 它执行了concreteClass继承的templateMethod()方法
      • 它执行了重写的variantStep()方法
    • 打印测试结果

2.2 代码

  • 代码
go 复制代码
package main

import "fmt"

// 定义抽象类
type AbstractClass struct {
	A int64
	B int64
	C int64
}

// 不可重写的方法,由于golang中没有这种权限控制,我们只能人为规定不在子类中重写。
func (a *AbstractClass) templateMethod() {
	a.A = a.A + 10
	a.invariantStep()
}

// 可重写的方法
func (a *AbstractClass) variantStep() {
	a.B = a.B + 10
}

// 本来是java中私有方法,子类不可见。由于golang中没有这些权限设置,我们只能人为规定不能由其他类调用,因此我们把它放到不可重写方法templateMethod()中执行
func (a *AbstractClass) invariantStep() {
	a.C = a.C + 10
}

func (a *AbstractClass) Get() {
	fmt.Printf("%+v", a)
}

// 具体实现类
type ConcreteClass struct {
	*AbstractClass
}

// 重写父类的variantStep方法
func (c *ConcreteClass) variantStep() {
	c.B = c.B - 10
}

// 定义具体实现类的执行方法
func (c *ConcreteClass) Execute() {
	c.templateMethod()
	c.variantStep()
}

func main() {
	//实例化抽象类
	abstractClass := &AbstractClass{
		A: 1,
		B: 1,
		C: 1,
	}
	//实例化具体实现类
	concreteClass := &ConcreteClass{
		AbstractClass: abstractClass,
	}
	//执行具体实现类的执行方法
	concreteClass.Execute()
	//查看结果
	concreteClass.Get()
}
  • 输出
shell 复制代码
&{A:11 B:-9 C:11}

2.3 类图

AbstractClass +Int A +Int B +templateMethod() -invariantStep() #variantStep() +Get() ConcreteClass #variantStep() +Execute()


相关推荐
这是谁的博客?27 分钟前
微服务架构设计模式深度解析:从拆分策略到容灾机制
微服务·设计模式·云原生·架构·架构设计·后端开发·分布式系统
姚不倒3 小时前
从零实现一个基于 Ollama + Go + MySQL 的 Text-to-SQL 智能体(M1 实战)
sql·mysql·云原生·golang
fan_music4 小时前
设计模式学习
c++·设计模式
乐观的山里娃6 小时前
【后编码时代 06】Vibe Coding + Superpowers 完全不够
设计模式·软件工程·ai编程
likerhood7 小时前
设计模式 · 责任链模式(Chain of Responsibility Pattern)
设计模式·责任链模式
追烽少年x9 小时前
STL中的设计模式(一)
c++·设计模式
乐观的山里娃10 小时前
【设计模式 10】抽象工厂:整体换季
设计模式
wlsh1511 小时前
Go 泛型笔记
golang
姚不倒11 小时前
从「LeetCode LRU 缓存」到「生产级 Go Web 服务」:我如何迈出工程化第一步
leetcode·缓存·云原生·golang
贵慜_Derek12 小时前
《从零实现 Agent 系统》连载 08|编排与工作流:从 Chat 到任务图
人工智能·设计模式·架构