引入
书接上回,我们来聊聊什么是模板方法模式?
相信学习设计模式的童鞋们都已经接触过模板了,这种方式的确方便,当你不知道这个算法有些步骤不确定或者不知道传入的是哪种变量的参数,这个时候最常用的方法就是先把算法的骨架做出来,用模板代替具体的步骤,而将一些步骤延迟到子类实现。
模板方法模式的定义
定义一个操作中算法的骨架,而将一些步骤延迟到子类中。
模板方法使子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
模板方法的适用场景
- 设计者需要给出一个算法的固定步骤,并将某些步骤的具体实现留给子类来实现
- 需要对代码进行重构, 将各个子类公共行为提取出来集中到一个共同的父类中以避免代码重复
模板方法模式的结构

大家看代码其实能更好的理解模板方法模式到底讲了个啥,怎么说呢?
就是有一个算法你可以写出它的大概了但是部分算法细节你不知道,或者你要延迟到子类当中(可能是核心算法,你不大会然后先空着,具体实现让别人来写,大概就是这个意图)
把你要下放的地方的方法定义成final类型,然后抽离出空着的方法,子类继承的时候就可以实现了。
抽象模板
import java.io.File;
public abstract class AbstractTemplate {
File[] allFiles;
File dir;
AbstractTemplate(File dir){
this.dir = dir;
}
//这里使用final的含义就是为了防止子类修改这个模板方法,而出现模板方法的混乱
public final void showFileName(){
allFiles = dir.listFiles();
sort();
printFiles();
}
//不知道这两个步骤该如何实现,所以直接定义成一个抽象方法放在模板中
protected abstract void sort();
protected abstract void printFiles();
}
具体模板
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
//具体模板1
public class ConcreteTemplate extends AbstractTemplate{
ConcreteTemplate(File dir) {
super(dir);
}
@Override
protected void sort() {
for (int i = 0; i < allFiles.length; i++) {
for (int j = i+1; j < allFiles.length; j++) {
if(allFiles[j].lastModified() < allFiles[i].lastModified()){
File file = allFiles[j];
allFiles[j] = allFiles[i];
allFiles[i] = file;
}
}
}
}
@Override
public void printFiles() {
for (int i = 0; i < allFiles.length; i++) {
long time = allFiles[i].lastModified();
Date date = new Date(time);
SimpleDateFormat matter = new SimpleDateFormat("yyyy-MM-dd:mm:ss");
String str = matter.format(date);
String name = allFiles[i].getName();
int k = i+1;
System.out.println(k+" "+name+"(" + str+ ")");
}
}
}
//具体模板2
public class ConcreteTemplate2 extends AbstractTemplate{
ConcreteTemplate2(File dir) {
super(dir);
}
@Override
protected void sort() {
for (int i = 0; i < allFiles.length; i++) {
for (int j = i+1; j < allFiles.length; j++) {
if(allFiles[j].length() < allFiles[i].length()){
File file = allFiles[j];
allFiles[j] = allFiles[i];
allFiles[i] = file;
}
}
}
}
@Override
public void printFiles() {
for (int i = 0; i < allFiles.length; i++) {
long fileSize = allFiles[i].length();
String name = allFiles[i].getName();
int k = i +1 ;
System.out.println(k +" "+name+"("+fileSize+"字节)");
}
}
}
应用程序入口
import java.io.File;
public class Application {
public static void main(String[] args) {
File dir = new File("d:/albert");
//选定第一种具体模板
AbstractTemplate template = new ConcreteTemplate(dir);
System.out.println(dir.getPath()+"目录下的文件:");
template.showFileName();
//选定第二种具体模板
AbstractTemplate template2 = new ConcreteTemplate2(dir);
System.out.println(dir.getPath()+"目录下的文件:");
template2.showFileName();
}
}
模板方法和继承区别
这个看起来很像继承重写方法,重要的就是这个final这个小技巧,直接禁止子类对这个模板方法的修改,子类只需要实现抽象模板开放出来的几个步骤。
- 抽象模板定义模板方法给出成熟的算法步骤,同时又不限制步骤的细节,具体模板实现算法细节不会改变整个算法的框架。
- 在抽象模板模式中,还可以通过钩子方法对某些步骤进行挂钩,具体模板通过钩子可以选择算法骨架中的某些步骤
本文介绍了模板方法模式的基本概念,阐述了在设计不确定步骤算法时如何运用此模式,通过代码示例展示了如何在抽象模板中定义固定步骤和延迟实现。重点讲解了模板方法与继承的区别,以及如何通过final关键字确保模板方法的稳定性。
1063

被折叠的 条评论
为什么被折叠?



