模板方法设计模式(Template Method Pattern):在父类中定义一个算法的结构,将结构中的某些操作抽象化,延迟到子类中实现,使得子类可以不改变该算法结构的情况下,重定义该算法的某些特定步骤。
模板方法的核心就是在父类中定义一个固定的流程,该流程有若干个步骤组成,具体的步骤可以有子类进行不同的实现,这样下来固定的步骤由于子类实现的不同,而产生不同的效果;
在日常生活中,模板方法非常常见;
这些流程是固定的,但是我们却可以更改每个流程的实现,例如某些地区的人喜欢吃辣,我就在“加调料”这一步多放点辣椒,最终的结果(出锅的菜)当然就会变辣,而有些地区喜欢吃酸的,我们就在“加调料”这一步多醋,最终的结果(出锅的菜)就会变得酸酸的;再比如在“切菜”这一步实现的不同,那么会影响菜的美观、在“翻炒”这一步实现的不同会影响菜的口感等等等…
在模板方法设计模式中主要有2个角色:

【案例】
在父类中定义一个算法骨架,用于计算某段代码的执行时间,分别编写两种实现,实现String拼接1W次,以及StringBuilder拼接100W此所消耗的时间;
package com.pattern.demo;
/**
* @author lscl
* @version 1.0
* @intro: 抽象模板: 定义算法骨架
*/
public abstract class AbstractGetTimeTemplate {
// 模板方法: 为了防止子类重写getTime方法 因此加上final修饰
public final long getTime(){
long start =System.currentTimeMillis();
code(); //将要执行的代码抽象化
long end=System.currentTimeMillis();
return end-start;
}
// 基本方法
public abstract void code();
}
package com.pattern.demo;
/**
* @author lscl
* @version 1.0
* @intro: 具体实现: 将基本方法进行实现,对String拼接1W次
*/
public class StringAppendGetTime extends AbstractGetTimeTemplate {
/**
* 计算1W次字符串拼接销毁的时间
*/
@Override
public void code() {
String str = "";
for (int i = 0; i < 10000; i++) {
str += i;
}
}
}
package com.pattern.demo;
/**
* @author lscl
* @version 1.0
* @intro: 具体实现: 将基本方法进行实现,对StringBuilder拼接100W次
*/
public class StringBuildAppendGetTime extends AbstractGetTimeTemplate {
/**
* 计算100W次StringBuild的拼接所消耗的时间
*/
@Override
public void code() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000000; i++) {
sb.append(i);
}
}
}
package com.pattern.demo;
/**
* @author lscl
* @version 1.0
* @intro:
*/
public class Demo01 {
public static void main(String[] args) {
AbstractGetTimeTemplate strAppendTemplate = new StringAppendGetTime();
long strTime = strAppendTemplate.getTime();
System.out.println("1W次字符串拼接消耗的时间: " + strTime);
System.out.println("-------------------");
AbstractGetTimeTemplate sbAppendTemplate = new StringBuildAppendGetTime();
long sbTime = sbAppendTemplate.getTime();
System.out.println("100W次StringBuilder拼接消耗的时间: " + sbTime);
}
}