文章目录
二十一、模板方法设计模式
21.1 模板方法设计模式简介
21.1.1 模板方法设计模式概述
模板方法设计模式(Template Method Pattern):在父类中定义一个算法的结构,将结构中的某些操作抽象化,延迟到子类中实现,使得子类可以不改变该算法结构的情况下,重定义该算法的某些特定步骤。
模板方法的核心就是在父类中定义一个固定的流程,该流程有若干个步骤组成,具体的步骤可以有子类进行不同的实现,这样下来固定的步骤由于子类实现的不同,而产生不同的效果;
在日常生活中,模板方法非常常见;
- 例如:炒菜流程都是固定的,洗菜、切菜、倒油、翻炒、加调料、再翻炒、出锅;
这些流程是固定的,但是我们却可以更改每个流程的实现,例如某些地区的人喜欢吃辣,我就在“加调料”这一步多放点辣椒,最终的结果(出锅的菜)当然就会变辣,而有些地区喜欢吃酸的,我们就在“加调料”这一步多醋,最终的结果(出锅的菜)就会变得酸酸的;再比如在“切菜”这一步实现的不同,那么会影响菜的美观、在“翻炒”这一步实现的不同会影响菜的口感等等等…
21.1.2 模板方法设计模式的UML类图
在模板方法设计模式中主要有2个角色:
- 1)抽象模板(AbstractClass):定义一个算法的骨架/结构/流程。他由模板方法和若干个基本方法来构成;
- 模板方法:算法的骨架的核心,按照顺序调用里面的基本方法来完成功能,该方法不能由子类重写,应该被final修饰;
- 基本方法:多个基本方法在一起工作组成了模板方法,基本方法由子类实现,在同一个算法骨架中,子类对基本方法的实现不同,将会实现不同的功能;
- 2)具体实现(ConcreteClass):实现抽象类中所定义的抽象方法。
21.3 模板方法设计模式的实现
【案例】
在父类中定义一个算法骨架,用于计算某段代码的执行时间,分别编写两种实现,实现String拼接1W次,以及StringBuilder拼接100W此所消耗的时间;
- 1)抽象模板:
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();
}
- 2)具体实现1:
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;
}
}
}
- 3)具体实现2:
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);
}
}
}
- 4)测试类:
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);
}
}
21.3 模板方法设计模式的优缺点
- 优点:
- 1)利用模板方法将相同的逻辑抽取到父类中,提高代码的复用性
- 2)将步骤的实现分离到不同的子类中,通过对子类不同的实现,实现不同的功能
- 缺点:
- 1)由于继承和抽象的特点,如果父类新增了抽象方法,则所有的子类都需要修改
- 2)造成类的数量增加,间接增加了系统实现的复杂度