图解设计模式之Template Method模式
什么是 Template Method模式
Template Method即模板方法,组成模板的方法被定义在父类中,而在子类中实现父类中定义的这些抽象方法。虽然子类中实现了父类的抽象方法,都有各自的实现,但是在父类定义了处理流程的框架,无论子类中的具体实现如何,处理的流程都会按照父类中所定义的那样进行,这种设计模式就是Template Method模式。
示例程序
示例程序比较简单,UML图如下:
![](https://img.haomeiwen.com/i16743411/d343ba0f0a2226af.png)
AbstractDisplay 类
public abstract class AbstractDisplay{
public abstract void open();
public abstract void print();
public abstract void close();
public final void display(){
open();
for(int i = 0; i < 5; i++){
print();
}
close();
}
}
AbstractDisplay类中,定义了三个抽象方法,由子类继承实现。而display方法则是处理流程的框架。display方法中,首先调用了open方法,然后调用了五次print方法,最后调用了close方法。至于open,print,close方法的具体实现交给继承AbstractDisplay的子类,而整体的框架流程,则是由父类的模板所定义出来的。
CharDisplay 类
public class CharDisplay extends AbstractDisplay{
private char ch;
public CharDisplay(char ch){
this.ch = ch;
}
public void open(){
System.out.print("<<");
}
public void print(){
System.out.print(ch);
}
public void close(){
System.out.println(">>");
}
}
当向CharDisplay类的构造函数中传入A这个字符串,那么最终显示的结果为:
<<AAAAA>>
StringDisplay 类
public class StringDisplay extends AbstractDisplay{
private String string;
private int length;
public StringDisplay(String string){
this.string = string;
this.length = string.length();
}
public void open(){
printLine();
}
public void print(){
System.out.println("|" + string + "|");
}
public void close(){
printLine();
}
private void printLine(){
System.out.print("+");
for(int i = 0;i < length;i++){
System.out.print("-");
}
System.out.println("+");
}
}
当向StringDisplay类的构造器中传入字符串Dobby时,输出如下:
+-----+
|Dobby|
|Dobby|
|Dobby|
|Dobby|
|Dobby|
+-----+
Main类
public class Main{
public static void main(String[] args){
AbstractDisplay d1 = new CharDisplay('H');
AbstractDisplay d2 = new StringDisplay("Dobby");
d1.display();
d2.display();
}
}
程序显示结果如下:
<<HHHHH>>
+-----+
|Dobby|
|Dobby|
|Dobby|
|Dobby|
|Dobby|
+-----+
Template Method模式中的角色
AbstractClass
AbstractClass负责实现模板方法,并且声明模板方法中所使用的抽象方法,这些抽象方法由继承它的子类来负责具体的实现。示例程序中由AbstractDisplay扮演这个角色。
ConcreteClass
负责实现AbstractClass中的抽象方法,示例程序中CharDisplay与StringDisplay扮演此角色。
Template Method的UML图
![](https://img.haomeiwen.com/i16743411/cfea1217e3ae4042.png)
对Template Method模式的思考
为什么使用 Template Method模式
使用模板方法模式的好处就在于,我们将算法编写到了父类中,无需再在子类里面定义算法的流程了。拿另外一个例子说明,比如做菜。做菜这件事,将基本的流程定义好:第一步,洗锅;第二步,放油;第三部,放菜;第四部,放调味料,第五步,炒菜......当做菜的流程被定义好,那么无论是西红柿炒鸡蛋,还是尖椒炒牛肉,都会按照做菜这个模板方法来进行,当然具体的步骤如放多少盐,倒多少油是做什么菜来决定的。试想一下没有模板方法,那么菜谱中每个菜的做法都被独立开,就会有大量的重复流程说明,模板方法的意义不仅仅在于定义算法的流程,更在于体现出了继承的优势,大大减少了重复的步骤,缩减了代码量。
为什么模板方法要使用final
如果使用了final定义模板方法,那么意图其实很明显,就是继承AbstractClass的子类无法重写模板方法。