先看一段代码:
public static void main(String[] args) {
// TODO Auto-generated method stub
long start = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
System.out.println("x");
}
long end = System.currentTimeMillis();
System.out.println(end-start);
}
求程序运行时间的代码,对于初学者来说这就算完成了,但是我们是有经验的开发人员(kidding),这段代码不符合万物皆对象的思想,将这段代码抽象到类中的代码如下:
public static void main(String[] args) {
GetTime gt = new GetTime();
gt.getTime();
}
}
class GetTime{
public void getTime() {
long start = System.currentTimeMillis();
code();
long end = System.currentTimeMillis();
System.out.println(end-start);
}
public void code() {
for (int i = 0; i < 10000; i++) {
System.out.println("x");
}
}
}
这样,面向对象的思想就有了,但是这里面还存在问题,code方法被写死,如果要测试其他的代码显得不那么灵活,这时可以考虑引进子类,在子类中去修改code方法。
public static void main(String[] args) {
Demo d = new Demo();
d.getTime();
}
}
abstract class GetTime{
public final void getTime() {
long start = System.currentTimeMillis();
code();
long end = System.currentTimeMillis();
System.out.println(end-start);
}
public abstract void code();
}
//延迟到子类中去实现
class Demo extends GetTime{
@Override
public void code() {
for (int i = 0; i < 10000; i++) {
System.out.println("x");
}
}
}
将父类抽象,只在父类中定义方法,延迟到子类中去实现,代码修改变得灵活。之所以叫做模板方法设计模式是因为在把计算开始时间和结束时间固定,中间添加代码,无论中间怎么添加都是这个模板,就像做砖头一样先找来模具,中间添加不同的材料就能做成不同的砖。
说一下缺点,可以看到如果要增加方法需要在父类中修改代码,我们学习任何一种模式都是为了使开发更灵活,所以要取其精华,抛弃他缺点的一面,利用友好的一面。
补充一下这个final,被final修饰是为了不让子类去重写getTime方法,重写了就没办法测出运行时间。final修饰的类不能被继承,final修饰的方法不能被重写,final不能与abstract同时出现,被final修饰的变量不能改变。这很好理解,final相当于定义一个不变的东西,而继承需要定义更强大的子类,相当于改变了,抽象方法或者类都需要重写抽象方法