定义:定义一个操作中算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变算法的结构即可重定义该算法中的某些特定步骤
类型:行为类模式
事实上,模板方法是编程中一个经常用到的模式。比如,给定一个整数数组,把数组中的数由大到小顺序,然后把排序之后的结果打印出来。这个需求大体可以分为两部分,排序和打印,打印功能好实现,排序优点麻烦。于是先把打印功能完成,排序功能另找别人做。
abstract class AbstractSort
{
protected abstract void sort(int[] array);
public void showSortResult(int[] array)
{
this.sort(array);
System.out.println("排序结果");
for (int i=0; i<array.length; i++)
{
System.out.println("%3s", array[i]);
}
}
}
class ConcreteSort extends AbstractSort
{
protected void sort(int[] array)
{
for(int i=0; i<arrat.length-1; i++)
{
selectSort(array, i);
}
}
private void selectSort(int[] array, int index)
{
int MinValue = 32767; // 最小值变量
int indexMin = 0; // 最小值索引
int temp; // 暂存变量
for(int i=index,; i<array.length; i++)
{
if(array[i] < MinValue) // 找到最小值
{
MinValue = array[i]; // 存储最小值
indexMin = i;
}
}
temp = array[index]; // 交换量数值
array[index] = array[indexMin];
array[indexMin] = temp;
}
}
以上就是模板方法模式。
模板方法模式的结构:
模板方法模式由一个抽象类和一个实现类通过继承结构组成,抽象类中得方法分为三种:
1)抽象方法:父类中只声明但不加以实现,而是定义好规范,然后由它的子类去实现
2)模板方法:由抽象类声明并加以实现,一般来说,模板方法调用方法来完成主要的逻辑功能,并且,模板方法大多会定义为final类型,指明主要的逻辑功能在子类中不能被 重写。
3)钩子方法:由抽象类声明并加以实现。但是子类可以去扩展,子类可以通过扩展钩子方法来影响模板方法的逻辑。
4)抽象类的任务是搭建逻辑的框架,通常由经验丰富的人员编写,因为抽象类的好坏直接决定了程序是否稳定性。
实现类用来实现细节。抽象类中的模板方法正式通过实现类扩展的方法来完成业务逻辑。只要实现类中的扩展方法通过了单元测试,在模板方法正确的前提下,整体功能一般不会出现大得错误。
模板方法的优点及适用场景:
容易扩展,一般来说,抽象类中的模板方法是不易发生改变的部分,而抽象方法是容易发生变化的部分,因为通过增加实现类一般可以很容易实现功能的扩展,符合开闭原则。
便于维护。对于模板方法模式来说,正式由于他们的主要逻辑相同,才使用了模板方法,假如不使用模板方法,任由这些相同的代码散乱的分布在不同的类中,维护起来是非常不方便。
比较灵活。因为有钩子方法,因此,子类的实现也可以影响父类中主逻辑的运行。但是,在灵活的同时,由于子类影响到了父类,违反了里氏替换原则,也会给程序带来风险。这就对抽象类的设计有了更高的要求。
在多个子类拥有相同的方法,并且这些方法逻辑相同时,可以考虑使用模板方法模式。在程序的主框架相同,细节不同的场合下,也比较适合使用这种模式。