1. 概述
模板方法(Template Method)用来定义算法的框架,将算法中的可变步骤定义为抽象方法,指定子类实现或重写。
1.1 角色
- AbstractClass(抽象类):用来定义算法框架和抽象操作
- templateMethod()方法:使用final修饰,包含了不可变的算法,不允许子类重定义它。
- invariantStep()方法,可见性为privat,子类不可见,也不能重定义。
- variantStep():可见性是protected,允许子类继承和重定义。
- ConcreteClass(具体实现类):用来实现算法框架中的某些步骤,完成与特定子类相关的功能
1.2 类图
2. 代码示例
2.1 设计
- 定义抽象类
AbstractClass
- 定义
templateMethod()
方法,包含了不可变的算法 - 定义
variantStep()
方法,是可以被子类重写的方法 - 定义
invariantStep()
方法,是抽象类的私有方法- 它应该是子类不可见的,但是go中无法真正实现,我们可以把它放到
templateMethod()
方法中执行,已达到子类视而不见的效果。
- 它应该是子类不可见的,但是go中无法真正实现,我们可以把它放到
- 定义
- 定义具体实现类
ConcreteClass
- 它继承了抽象类
AbstractClass
- 它的方法
variantStep()
重写了父类的variantStep()
方法 - 它的
Execute()
是它的执行方法
- 它继承了抽象类
- 调用
- 实例化抽象类
abstractClass
- 实例化具体实现类
concreteClass
,继承了抽象类abstractClass
- 执行
concreteClass
的Execute()
方法- 它执行了
concreteClass
继承的templateMethod()
方法 - 它执行了重写的
variantStep()
方法
- 它执行了
- 打印测试结果
- 实例化抽象类
2.2 代码
- 代码
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()
}
- 输出
&{A:11 B:-9 C:11}