模板方法模式是一种行为设计模式,它定义了一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下重新定义算法的某些特定步骤。
模板方法模式作用
代码复用:将公共部分的代码放在父类中,避免重复代码。
扩展性:子类可以重写父类中的某些方法,实现不同的行为。
控制流程:父类控制算法的流程,子类实现具体步骤。
算法的不变部分和可变部分分离:例如,框架中的模板方法。
一次性实现一个算法的不变部分,并将可变部分留给子类实现:例如,游戏开发中的游戏框架。
多个子类有公有的方法,并且逻辑基本相同:例如,不同类型的报告生成。
以下是一个使用模板方法模式的Go语言示例,模拟了不同类型的文档生成过程:
package main
import (
"fmt"
)
// Document 模板类,定义文档生成的骨架
type Document interface {
open()
writeContent(content string)
close()
GenerateDocument(content string)
}
// BaseDocument 基础文档类,实现模板方法
type BaseDocument struct{}
func (b *BaseDocument) open() {
fmt.Println("Opening document")
}
func (b *BaseDocument) writeContent(content string) {
fmt.Printf("Writing content: %s\n", content)
}
func (b *BaseDocument) close() {
fmt.Println("Closing document")
}
func (b *BaseDocument) GenerateDocument(content string) {
b.open()
b.writeContent(content)
b.close()
}
// PDFDocument PDF文档类,重写writeContent方法
type PDFDocument struct {
BaseDocument
}
func (p *PDFDocument) writeContent(content string) {
fmt.Printf("Writing content in PDF format: %s\n", content)
}
// WordDocument Word文档类,重写writeContent方法
type WordDocument struct {
BaseDocument
}
func (w *WordDocument) writeContent(content string) {
fmt.Printf("Writing content in Word format: %s\n", content)
}
func main() {
// 创建PDF文档实例
pdfDoc := &PDFDocument{}
pdfDoc.GenerateDocument("Hello, this is a PDF document.")
// 创建Word文档实例
wordDoc := &WordDocument{}
wordDoc.GenerateDocument("Hello, this is a Word document.")
}
目的:接口定义了一组方法的签名,但不提供这些方法的具体实现。实现接口的类必须提供这些方法的具体实现。
灵活性:接口提供了一种完全抽象的方式,实现类可以自由地定义方法的具体行为。
使用场景:适用于需要定义一组方法,但具体实现由不同类来完成的情况。
目的:模板方法模式定义了一个算法的骨架,将一些步骤延迟到子类中。它提供了一个模板方法,该方法调用其他抽象方法或具体方法来完成整个算法。
灵活性:模板方法模式提供了一种半抽象的方式,父类定义了算法的骨架,子类可以重写某些步骤以实现特定的行为。
使用场景:适用于算法的不变部分和可变部分分离的情况,以及需要控制算法流程但允许子类重写某些步骤的情况。
抽象程度:
接口:完全抽象,不提供任何实现。
模板方法模式:部分抽象,提供了一个算法的骨架,但允许子类重写某些步骤。
控制流程:
接口:不控制流程,实现类可以自由地定义方法的具体行为。
模板方法模式:控制流程,父类定义了算法的流程,子类只能重写特定的步骤。
代码复用:
接口:不提供代码复用,每个实现类都需要重新实现所有方法。
模板方法模式:提供代码复用,父类中可以包含公共的代码,子类只需重写特定的方法。