模板模式我觉得在Android的开发中是最长用到的,基本是随处可见的,认识该模式,有助于我们对Android的源码及框架有一个更深层次的认识。那什么是模板模式呢,模板模式就是定义一个基本框架,将其中的一些方法延迟到子类中执行实现。就比如我们去餐馆吃饭,基本步骤肯定为找到座位,点菜,上菜,吃饭,买单五个过程,其中点菜这个过程是可变的,我们点的菜可多可少,其他都是固定的,那么我们就可以写在一个固定的抽象类里形成一个基本框架,我们的子类继承该抽象类,对其中可变的方法进行复写。
下面我们就来看一个例子。
/*
* 抽象基类,为所有子类提供一个算法框架
*
* 提神饮料
*/
public abstract class RefreshBeverage {
/*
* 制备饮料的模板方法
* 封装了所有子类共同遵循的算法框架
*/
public final void prepareBeverageTemplate(){
//步骤1 将水煮沸
boilWater();
//步骤2 泡制饮料
brew();
//步骤3 将饮料倒入杯中
pourInCup();
if(isCustomerWantsCondiments()){
//步骤4 加入调味料
addCondiments();
}
}
/*
* Hook, 钩子函数,提供一个默认或空的实现
* 具体的子类可以自行决定是否挂钩以及如何挂钩
* 询问用户是否加入调料
*/
protected boolean isCustomerWantsCondiments() {
return true;
}
/*
* 基本方法,将水煮沸
*/
private void boilWater() {
System.out.println("将水煮沸");
}
/*
* 基本方法,将饮料倒入杯中
*/
private void pourInCup() {
System.out.println("将饮料倒入杯中");
}
/*
* 抽象的基本方法,泡制饮料
*/
protected abstract void brew();
/*
* 抽象的基本方法, 加入调味料
*/
protected abstract void addCondiments();
}
我们定义了一个制备饮料的模板类,其中我们一定要注意prepareBeverageTemplate()方法的关键字一定为final,保证子类只能修改可见的方法,保证模板框架的稳定,需要子类实现的方法定义为Protected属性并且为一个抽象类,由子类来对其*发挥,就像我们Android每一个类一般都会继承Activity类,复写其中的oncreate()方法一样,其属性也为protected.不想在子类可见的方法,我们需将其定位为private属性并且写好方法体。
我们还可以发现我们在其中定义了一个isCustomerWantsCondiments()方法,这个方法就是hook钩子,增加模板框架的灵活性,该方法可以在子类中重写,以此来判断是否需要执行某个方法。
public class Tea extends RefreshBeverage {
@Override
protected void brew() {
System.out.println("用80度的热水浸泡茶叶5分钟");
}
@Override
protected void addCondiments() {
System.out.println("加入柠檬");
}
@Override
/*
* 子类通过覆盖的形式选择挂载钩子函数
* @see com.imooc.pattern.template.RefreshBeverage#isCustomerWantsCondiments()
*/
protected boolean isCustomerWantsCondiments(){
return false;
}
}
我们写了一个泡茶的类,并将hook方法复写返回false, 取消了制备饮料的第四步。那么我们什么时候需要使用模板类呢?
(1)算法或操作遵循相似的逻辑时
(2)重构时(把相同的代码抽入到父类中),提高程序的复用性
(3)重要复杂的算法,核心算法设计为模板算法