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

概念:
模板方法模式(Template Method Pattern),又叫模板模式(Template Pattern),使用 继承 机制,把 通用步骤 和 通用方法 放到 父类 中,把 具体实现 延迟到 子类 中实现。使得实现符合 开闭原则
因为 Golang不提供 继承机制,需要使用 匿名组合 模拟实现 继承。
此处需要注意:因为父类需要调用子类方法,所以子类需要匿名组合父类的同时,父类需要持有子类的引用。
简单说,模板方法模式 定义一个操作中的 算法的骨架,而将 一些步骤 延迟到 子类中,使得子类可以 不改变一个算法的结构,就可以 重定义该算法的某些特定步骤
这种类型的设计模式属于 行为型模式
在 模板方法模式 的 父类 中,我们可以 定义一个 方法,它默认 不做任何事,子类可以 视情况要不要覆盖它,该方法称为“钩子”

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关键字, 防止 子类重写模板方法
使用场景:当要完成在 某个过程,该过程要执行 一系列步骤 ,这一系列的步骤 基本相同,但其 个别步骤 在 实现时 可能不同,通常考虑用 模板方法模式 来处理

浙公网安备 33010602011771号