------- android培训、java培训、期待与您交流! ----------
1. 示例
我们通过一个例子来引入模板设计模式。
需求:获取一段程序运行的时间。
分析:获取程序开始和结束的时间,并将这两个时间相减即可。
实现方法:通过System类的currentTimeMillis()静态方法获取当前时间的毫秒值。该毫秒值是当前时间与协调世界时1970年1月1日午夜之间的时间差(摘自API文档)。由于这个毫秒值很大,通常会超出整型变量的范围,因此用长整型变量long来定义毫秒值。我们将这个获取时间差的方法定义到一个类中,方便以后复用。该类中要定义两个方法,一个方法专门用于计算时间差,该方法要定义为final,防止子类复写并修改导致无法实现计算时间的目的;另一个方法为抽象方法,子类继承该类以后复写这个抽象方法,而复写的内容就是需要计算运行时间的子类方法。之所以要用子类继承的方式,而不是在某个类中定义获取时间方法,主要是为了提高代码的复用性,为所有类服务。否则的化,不同类的不同方法想要计算运行时间,每次都要重复写代码,效率很低。
具体步骤:
1) 由于需要定义抽象方法,因此要定义一个抽象类GetTime。
2) GetTime类中定义一个抽象方法run()供子类复写,复写的内容就是子类需要计算运行时间的方法。
3) 再定义一个计算时间的final方法getTime()。先获取开始时的毫秒值,然后调用上述run()方法,run()方法运行结束以后,再获取结束时的毫秒值,最后输出这两个毫秒值的差值。
4) 定义一个子类,子类内部定义一个run()方法,这个run方法就是需要计算运行试件的方法,复写父类的run方法即可。
5) 在主函数中创建一个子类对象,并调用子类对象的getTime方法。
代码:
代码1:
abstract class GetTime
{
//确定的方法
public final void getTime()
{
/*
分别获取run方法开始和结束的毫秒值,最后输出两值的差
*/
long start = System.currentTimeMillis();
run();
long end = System.currentTimeMillis();
System.out.println("运行时间为:"+(end- start)+"毫秒");
}
//不确定的方法
abstract public void run();
}
class Demo extends GetTime
{
//计算50位斐波那契数列
public void run()
{
//先打印前两位
System.out.print(1+"\t");
System.out.print(1+"\t");
//由于已经输出了2位,所以计数器从第3位开始
int count = 3;
for(long x = 1, y = 1; count <= 50; z++)
{
/*
当前一位大于小于后一位,将两位的和赋予前一位,并输出
反之,将两位的和赋予后一位,并输出
这样做可以保证按整数的自然排序输出
*/
if(x <= y)
{
x = x + y;
System.out.print(x+"\t");
}
else
{
y = x + y;
System.out.print(y+"\t");
}
//每输出五位数就进行换行
if(z % 5 == 0)
System.out.println();
}
System.out.println("共算出"+(count-1)+"位斐波那契数列");
}
}
class ExtendsTest
{
public static void main(String[] args)
{
Demo d = new Demo();
d.getTime();
}
}
2. 模板设计模式
模板设计模式:在定义某个类的时候,类的一些方法是确定的,另一些方法是不确定的,而确定的方法需要使用不确定的方法,那么这时将不确定的方法暴露出去,由该类的子类去复写实现具体方法。
模板设计模式的优点:
1) 提高代码的扩展性,只要子类继承该类就可以使用计算时间的方法。
2) 提高的代码的复用性,不必每次重新定义计算时间的方法。
3. 生活中的模板
什么叫模板?打个比方,制作蛋糕的时候,除了诸如鸡蛋、面粉、糖等等各种配料以外,最重要的是模子。将上述配料混合在一起以后,倒进模子里面,加热烤熟就是蛋糕。这里的模子就是我们所说的模板。有了这个模板,只要换配料就能制作其他食品,比如月饼,而不管制作什么食品,它们的形状都是一样的,这就是模板的作用。
最后再提一点,事实上,代码1GetTime类中的run方法不一定是抽象方法,它本身可以对外提供某种具体的方法,但如果子类需要改变该方法的实现方式或者进行优化,就可以进行复写。同样,getTime方法也不一定就是final的,子类也可以按照实际需要进行复写。