将具体处理交给子类——模板方法模式
模板方法模式,在父类中定义处理流程的框架,在子类中实现具体处理。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
模板方法模式中有如下两种角色:
AbstractClass是抽象类,定义并实现了一个模板方法。这个模板方法一般是一个具体方法,它给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现。顶级逻辑也有可能调用一些具体方法。
ConcreteClass是具体类,实现父类所定义的抽象方法。每个AbstractClass都可以有任意多个ConcreteClass与之对应,而每一个ConcreteClass都可以给出这些抽象方法的不同实现,从而使得顶层逻辑的实现各不相同。
以将字符以及字符串连续显示5次为例,有如下示例。在示例程序中一共出现AbstractDisplay,CharDisplay,StringDisplay,Main这4个类。AbstractDisplay中定义了模板方法,而且在该方法中依次调用了三个抽象方法;而实际上实现这三个抽象方法的是AbstractDisplay的子类CharDisplay类和StringDisplay类。
package templateMethod;
public abstract class AbstractDisplay { //抽象类AbstractDisplay
public abstract void startFlag(); //交给子类去实现抽象方法startFlag()
public abstract void print(); //交给子类去实现抽象方法print()
public abstract void endFlag(); //交给子类去实现抽象方法endFlag()
public final void display() //模板方法,给出逻辑的骨架,逻辑组成是一些抽象操作。
{
startFlag();
for(int i=0;i<5;i++)
{
print();
}
endFlag();
}
}
package templateMethod;
public class CharDisplay extends AbstractDisplay {
private char ch; //需要显示的字符
public CharDisplay(char ch)
{
this.ch=ch;
}
@Override
public void startFlag() {
System.out.print("<<");
}
@Override
public void print() {
System.out.print(ch);
}
@Override
public void endFlag() {
System.out.println(">>");
}
}
package templateMethod;
public class StringDisplay extends AbstractDisplay {
private String string; //需要显示的字符串
private int width;
public StringDisplay(String string) {
this.string=string;
this.width=string.length();
}
@Override
public void startFlag() {
printLine();
}
@Override
public void print() {
System.out.println("|"+string+"|");
}
@Override
public void endFlag() {
printLine();
}
private void printLine() {
System.out.print("+");
for(int i=0;i<width;i++)
{
System.out.print("-");
}
System.out.println("+");
}
}
package templateMethod;
public class Main {
public static void main(String[] args) {
AbstractDisplay d1=new CharDisplay('H');
AbstractDisplay d2=new StringDisplay("Hello World.");
d1.display();
d2.display();
}
}
运行结果: