模板方法模式
概述
现实生活中很多事情的完成过程都包含几个基本步骤,例如请客吃饭,无论吃什么,一般都包含点单、吃东西、买单几个步骤,到底吃什么则具体情况具体分析
既然这几个步骤的次序是固定的,于是我们创建一个新的方法叫“请客”,在其中调用了点单、吃东西和买单,同时指定它们的执行次序,我们称这个“请客”为模板方法,“点单”、“吃东西”、“买单”都是“请客”过程中的一个步骤,它们称为基本方法。其中“吃东西”可以有多种吃法,如吃饭、吃面条、吃烧烤,因此需要提供不同的“吃东西”方法的实现。假设用代码实现上述方法,我们可以把相同代码放在父类,如“点单”和“买单”,而将不同方法实现放在不同的子类,如“吃东西”,这样一来提高了代码的复用性,还可以利用面向对象的多态性
模板方法模式在抽象类中定义了一个称为模板方法的方法,在这个方法中定义其他基本方法的执行步骤,而基本方法的实现可以放在抽象类,也可以放在其子类
模式分析
模板方法模式先在抽象类的模板方法中指定执行步骤,将相同步骤对应的方法在抽象父类中实现,而不同的步骤只在抽象父类中进行声明。由于面向对象的多态性,子类中定义的方法将覆盖父类中定义的方法
抽象类(AbstractClass)中定义一系列基本操作(primitiveOperation),这些基本操作可以是具体的,也可以是抽象的,每一个基本操作对应算法的一个步骤,在其子类中可以重定义并实现一个算法的各个步骤。同时在抽象类中实现了一个模板方法(templateMethod),用于定义一个算法的骨架,调用基本操作
具体子类(ConcreteClass)用于实现在父类中定义的抽象基本操作,也可以覆盖在父类中实现的具体基本操作。
基本方法是实现各个步骤的方法,是模板方法的组成部分,基本方法又可以分为三种:
- 抽象方法:一个抽象方法由抽象类声明,由其具体子类实现
- 具体方法: 一个具体方法由一个抽象类或具体类声明并实现,其子类可以进行覆盖
- 钩子方法:一个钩子方法由一个抽象类或具体类声明并实现,而其子类可能会加以扩展。通常在父类中给出的实现是一个空实现,作为该方法的默认实现,当然也可以提高一个非空的默认实现
钩子方法有两类,一类是可以控制具体步骤的执行,比如说我们希望在不同条件下执行模板方法中的不同步骤,就可以定义一个返回类型为布尔值的钩子方法,用于进行条件判断,如果条件满足则执行某一步骤,否则某一步骤不执行
public void template() {
open();
display();
if(isPrint()) {
print();
}
}
public boolean isPrint(){
return true;
}
如果不希望方法执行,可以在其子类在覆盖钩子方法,修改返回值即可