设计模式-16-模板方法模式

模板方法模式是一种行为设计模式, 它在超类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤

逻辑结构

Template

代码实现

代码路径:https://github.com/XBoom/DesignPatterns/tree/main/15_Template

  1. 定义一个模板方法,其中包含算法的骨架

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // Template 模板流程
    type Template interface {
    Step1()
    Step2()
    Step3()
    }

    func (t *ConcreteTemplate) TemplateMethod() {
    t.step1()
    t.step2()
    t.step3()
    }
  2. 定义一个模板的实现(很重要,因为 Golang 不能直接继承)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    type ConcreteTemplate struct{}

    func (t *ConcreteTemplate) step1() {
    fmt.Println("ConcreteTemplate:step1")
    }

    func (t *ConcreteTemplate) step2() {
    fmt.Println("ConcreteTemplate:step2")
    }

    func (t *ConcreteTemplate) step3() {
    fmt.Println("ConcreteTemplate:step3")
    }
  3. 接着,有一个模板的操作方法

    1
    2
    3
    4
    5
    func GetResult(t Template) {
    t.Step1()
    t.Step2()
    t.Step3()
    }
  4. 构建另外两个模板方法,嵌套了 ConcreteTemplate,并重写了部分步骤

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    type ConcreteTemplateA struct {
    ConcreteTemplate
    }

    func (t *ConcreteTemplateA) Step1() {
    fmt.Println("ConcreteTemplateA:step1")
    }

    type ConcreteTemplateB struct {
    ConcreteTemplate
    }

    func (t *ConcreteTemplateB) Step3() {
    fmt.Println("ConcreteTemplateB:step3")
    }

运行

1
2
GetResult(&ConcreteTemplateA{})
GetResult(&ConcreteTemplateB{})

结果

1
2
3
4
5
6
ConcreteTemplateA:step1
ConcreteTemplate:step2
ConcreteTemplate:step3
ConcreteTemplate:step1
ConcreteTemplate:step2
ConcreteTemplateB:step3

类似于重写林父类方法

总结

  1. 模板方法模式只适用于具有相似算法结构的场景,如果算法结构非常不同,则不太适合使用该模式
  2. 可将重复代码提取到一个超类中
  3. 当一个算法的具体实现需要发生改变时,可以通过在子类中重写抽象方法来灵活地扩展算法
  4. 当一个算法需要在多个子类中共享时,可以将其骨架放在父类中实现