HeadFirst 设计模式 - Chapter8 模板方法设计模式

1676 查看

定义

在一个方法中定义了一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

是一种重要的代码复用的重要技巧。从实现的角度来说,这符合封装变化的思想。同时,钩子是被声明在抽象类中,但是只有空的或者默认的算法实现,由子类决定是否进行覆盖,对算法的不同点进行挂钩。当两个或多个类执行的操作可以抽象为统一的步骤算法,只是在每步细节的实现上有差异,则可以依赖模板方法构造一种继承体系(有变化就封装继承体系)

模板 = 方法 = 一组步骤(任何步骤都可以是抽象的,由子类负责实现)这可以确保算法的结构保持不变,同时由子类提供实现。

类图如下:
]

hook是对那些子类可以选择实现的功能,在抽像类中给出一个简单的默认实现,让子类决定去不去覆盖
这里涉及到两个角色:
抽象模板

  • 定义了一个或多个抽象操作,以便让子类实现。这些抽象操作叫做基本操作,它们是一个顶级逻辑的组成步骤。
  • 定义并实现了一个模板方法。这个模板方法一般是一个具体方法,它给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现。顶级逻辑也有可能调用一些具体方法。

具体模板

  • 实现父类所定义的一个或多个抽象方法,它们是一个顶级逻辑的组成步骤。
  • 每一个抽象模板角色都可以有任意多个具体模板角色与之对应,而每一个具体模板角色都可以给出这些抽象方法(也就是顶级逻辑的组成步骤)的不同实现,从而使得顶级逻辑的实现各不相同。
javaabstract class AbstractClass{
    final void templateMethod(){
        primitiveOperation1();
        primitiveOperation2();
        concreteOperation();
        hook();
    } // 声明为final 以免子类改变这个算法的顺序
    abstract void primitiveOperation1(); // 子类实现
    abstract void primitiveOperation2(); // 子类实现
    void concreteOperation(){
    }
    void hook(){}
}

何时使用抽象方法?何时使用hook?
当你的子类必须提供算法中某个步骤的实现时,就用抽象方法;
如果算法中这个步骤是可选的,就用hook. 通过使用钩子,让抽象类的子类的负荷减轻itu