【Go-设计模式】模板方法模式 详解

shadowLogo

概念:

模板方法模式(Template Method Pattern),又叫模板模式(Template Pattern),使用 继承 机制,把 通用步骤通用方法 放到 父类 中,把 具体实现 延迟到 子类 中实现。使得实现符合 开闭原则

因为 Golang不提供 继承机制,需要使用 匿名组合 模拟实现 继承
此处需要注意:因为父类需要调用子类方法,所以子类需要匿名组合父类的同时,父类需要持有子类的引用。

简单说,模板方法模式 定义一个操作中的 算法的骨架,而将 一些步骤 延迟到 子类中,使得子类可以 不改变一个算法的结构,就可以 重定义该算法的某些特定步骤

这种类型的设计模式属于 行为型模式

在 模板方法模式 的 父类 中,我们可以 定义一个 方法,它默认 不做任何事,子类可以 视情况要不要覆盖它,该方法称为“钩子

template


UML:

uml

  • AbstractClass 抽象类
    实现了 模板方法(template),定义了 算法的骨架具体子类 需要去实现 其它的抽象方法
  • ConcreteClass
    实现 抽象方法,以完成 算法 中 特定子类 的 相关步骤

示例:

模板类:

type Template struct {
	Implement
}

func (this Template) DoSomething() {
	this.Operation1()
	fmt.Println("addtional Operation4...")
	this.Operation2()
	fmt.Println("addtional Operation5...")
	this.Operation3()
}

实现类 接口:

type Implement interface {
	Operation1()
	Operation2()
	Operation3()
}

具体的实现类:

type ConcreteClass struct {
	Template
}

func (this ConcreteClass) Operation1() {
	fmt.Println("do Real Operation1...")
}

func (this ConcreteClass) Operation2() {
	fmt.Println("do Real Operation2...")
}

func (this ConcreteClass) Operation3() {
	fmt.Println("do Real Operation3...")
}

func NewConcreteClass() ConcreteClass {
	concreteClass := ConcreteClass{}
	template := Template{
		Implement: concreteClass,
	}

	concreteClass.Template = template
	return concreteClass
}

测试:

package main

import "DemoProject/design/base23/template"

func main() {
	// template
	concreteClass := template.NewConcreteClass()

	concreteClass.DoSomething()
}

注意事项:

基本思想算法只存在于一个地方,也就是在 父类 中,容易修改
需要修改算法时,只要修改 父类的模板方法 或者 已经实现的某些步骤,子类就会 继承这些修改

实现了 最大化代码复用
父类的模板方法已实现的某些步骤被子类 继承而直接使用

统一了算法,也 提供了很大的灵活性
父类的模板 方法确保了 算法结构 保持不变,同时由 子类提供部分步骤实现

不足之处每一个不同的实现 都需要 一个子类实现,导致 类的个数增加,使得 系统更加庞大

一般 模板方法 都加上 final关键字, 防止 子类重写模板方法

使用场景:当要完成在 某个过程,该过程要执行 一系列步骤 ,这一系列的步骤 基本相同,但其 个别步骤实现时 可能不同,通常考虑用 模板方法模式 来处理

posted @ 2021-12-16 09:04  在下右转,有何贵干  阅读(265)  评论(0)    收藏  举报