Template模式是在父类中定义处理流程的框架,在子类中实现具体处理的模式。
一、示例程序
将字符和字符串循环显示5次的程序
在AbstractDisplay类中定义了display方法,而且在该方法中依次调用open、print、close这3个方法,虽然这3个方法已经在AbstractDisplay中被声明了,但都是没有尸体的抽象方法。这里调用抽象方法的display方法就是模板方法。
而实际上实现了open、print、close这3个抽象方法的是AbstractDisplay的子类CharDisplay类和StringDisplay类。
AbstractDisplay类:
package TemplateMethod;
//抽象模板中使用抽象而不是用接口的原因是,抽象模板的父类中有模板方法,模板方法不是抽象方法,而接口中的方法要求全部是抽象的,
//所以这里不能使用接口,接口中是无法实现方法的
//抽象类中既可以有抽象方法,也可以有普通方法
public abstract class AbstractDisplay {
public abstract void open();
public abstract void print();
public abstract void close();
//final字段在继承该类的子类中此方法不能被重写
public final void display(){
open();
for(int i=0;i<5;i++){
print();
}
close();
}
}
CharDisplay类:
package TemplateMethod;
//抽象类的子类,继承抽象类,实现抽象方法
public class CharDisplay extends AbstractDisplay {
private char ch;
public CharDisplay(char ch) {
// TODO Auto-generated constructor stub
this.ch = ch;
}
@Override
public void open() {
// TODO Auto-generated method stub
System.out.print("<<");
}
@Override
public void print() {
// TODO Auto-generated method stub
System.out.print(ch);
}
@Override
public void close() {
// TODO Auto-generated method stub
System.out.println(">>");
}
}
StringDisplay类:
package TemplateMethod;
//抽象类的子类,继承抽象类,实现抽象方法
public class StringDisplay extends AbstractDisplay {
private String string;
private int width;
public StringDisplay(String string) {
// TODO Auto-generated constructor stub
this.string = string;
this.width = string.getBytes().length;
}
@Override
public void open() {
// TODO Auto-generated method stub
printLine();
}
@Override
public void print() {
// TODO Auto-generated method stub
System.out.println("|"+string+"|");
}
@Override
public void close() {
// TODO Auto-generated method stub
printLine();
}
private void printLine(){
System.out.print("+");
for(int i=0;i<width;i++){
System.out.print("-");
}
System.out.println("+");
}
}
总结:抽象类角色不仅负责实现模板方法,还负责声明在模板方法中所使用到的抽象方法,此处即程序流程中使用到的算法,这些抽象方法的实现有具体类实现。
具体类负责实现抽象类角色中定义的抽象方法。