一、什么是模板方法设计模式
考虑一个问题,我们想知道执行一段程序耗时多长,怎么做呢?
这个问题很简单:
1.在程序执行前,获取一下当时的时刻t1;
2. 然后跑那段需要测试耗时的程序;
3. 执行完后,获取一下当时的时刻t2;
4. 那段程序的耗时就为(t2-t1)。
用代码实现也是比较简单。
过了几天,需要知道另一个程序的耗时,怎么办呢?把上面的代码拷过来,把步骤3替换成新的被测程序吗?以后有新的程序需要测试耗时,怎么办呢?有没有更好的解决这个问题的方法呢?
通过分析知道,测试一段程序的耗时,这个流程是固定的:获取程序开始和结束的时刻并相减,其中变化的是被测的程序的不同。
即在定义功能时,功能的一部分是确定的,但有一部分是不确定的,而确定部分在使用不确定的部分,那么这时就把不确定部分暴露出去,由子类去具体实现。
这就是模板方法设计模式。
模板方法设计模式比较官方的说法是:
定义一个操作中的某种算法的框架,而将一些步骤延迟到子类中。模板方法模式使得子类在不改变一个算法结构的前提下,对这些步骤进行个性化定义。
二、模板方法设计模式的例子
使用java实现前面测试程序耗时的功能可以这样做:
定义模板抽象类:
abstract class GetTime
{
public final void getTime() //算法框架固定,final不让子类重写该方法
{
long start = System.currentTimeMillis(); //算法中的确定部分
runCode(); //算法中的不确定部分
long end = System.currentTimeMillis(); //算法中的确定部分
System.out.println("程序耗时为:" + (end - start));
}
public abstract void runCode(); //算法中不确定部分让子类去具体实现
}
在这个抽象类中,定义好了测试一段程序耗时这个功能的实现,具体是哪一段程序呢,延迟到子类中具体指明。
测试程序1的耗时,则继承上面那个抽象类,把程序1写入runCode()方法中:
class Programming1Time extends GetTime
{
public void runCode()
{
//程序1的代码
for(int i=0; i<1000; i++)
{
System.out.print(i);
}
}
}
编写客户端测试程序:
class TestDemo
{
public static void main(String []argc)
{
getTime(new Programming1Time());
}
public static void getTime(GetTime gt)
{
gt.getTime();
}
}
一个月后,一个新的程序2需要测试耗时,则继承上面那个抽象类,把程序2写入runCode()方法中:
class Programming2Time extends GetTime
{
public void runCode()
{
//程序2的代码
for(int i=0; i<5000; i++)
{
System.out.print(i);
}
}
}
客户端相应修改:
class TestDemo
{
public static void main(String []argc)
{
getTime(new Programming2Time());
}
public static void getTime(GetTime gt)
{
gt.getTime();
}
}
以后有新的程序需要测试耗时,只要继承这个类,实现runCode()方法就可以测试了,具备了很强的扩展性。
总结
模板方法设计模式主要是利用了类的继承和多态特点,优点就是可以将固定不变的部分进行封装,然后需要变化的部分子类实现自己扩展。