模板方法模式(Template),定义一个操作中算法的框架,而将一些步骤延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
举个栗子:小明想在学习过后去运动或者上会网,那么小明在学习某门课程过后一定会搞点事情,而这些事情是可变化的,谁也不知道他要干什么,所以我们需要在它需要的时候进行“实现”。
类图
示例代码
//package com.dlut.designpattern.template;
public abstract class AbstractClass {
public void beforeLearn(){};//钩子方法
public abstract void learn();
public abstract void afterLearn();
public final void TemplateMethod(){
beforeLearn();
learn();
afterLearn();
}
}
class ExerciseAfterLearn extends AbstractClass{
public void learn() {
System.out.println("学英语:A,B,C...");
}
public void afterLearn() {
System.out.println("打篮球去...");
}
}
class InternetAfterLearn extends AbstractClass{
public void beforeLearn(){
System.out.println("预习化学...");
}
public void learn() {
System.out.println("学化学:氢氦锂铍硼...");
}
public void afterLearn() {
System.out.println("刷刷微博...");
}
}
public class Client {
public static void main(String[] args) {
AbstractClass ac=new ExerciseAfterLearn();
ac.TemplateMethod();
ac=new InternetAfterLearn();
ac.TemplateMethod();
}
}
输出结果:
学英语:A,B,C…
打篮球去…
预习化学…
学化学:氢氦锂铍硼…
刷刷微博…
在代码中,我们可以看到一个新的概念:钩子方法。
钩子方法:由一个抽象类或具体类声明并实现,而其子类可能会加以扩展。通常在父类中给出的实现是一个空实现,并以该空实现作为方法的默认实现,当然钩子方法也可以提供一个非空的默认实现。
这样使得我们的模式有了一定的可扩展性。
模版方法:由抽象类声明并加以实现。一般来说,模版方法调用抽象方法来完成主要的逻辑功能,并且,模版方法大多会定义为final类型,指明主要的逻辑功能在子类中不能被重写。
模板方法模式也有其缺点:需要为每一个基本方法的不同实现提供一个子类,如果父类中可变的基本方法太多,将会导致类的个数呈爆炸型增长,设计也更加抽象。此时,可结合桥接模式来进行设计。
参考: