什么是模板方法
在父类中会定义一个框架(方法),在这个框架中有一套程序处理流程。这个处理流程由若干个其他方法按照有意义的顺序组成,但这若干个方法的具体实现由子类负责,父类只负责调用。
模板方法的示例程序
涉及到的类:
类名 | 说明 |
AbstractDisplay | 包含三个抽象方法:open()、close()、print() 以及一个已实现的方法display()。 |
CharDisplay | 实现了open()、close()、print()方法的类 |
StringDisplay | 实现了open()、close()、print()方法的类 |
Main | 测试程序用的类 |
类和方法的详情参照下文的代码。
AbstractDisplay
public abstract class AbstractDisplay {
public abstract void open();
public abstract void close();
public abstract void print();
//该方法定义了处理流程的框架
//此处用final进行修饰的原因: final修饰的方法不能被子类重写,这样就保证了具体的算法流程由类控制,子类只负责方法的实现
public final void display(){
open();;
for(int i = 0; i < 5; i++){
print();
}
close();
}
}
CharDisplay
public class CharDisplay extends AbstractDisplay{
private char c;
public CharDisplay(char c) {
this.c = c;
}
@Override
public void open() {
System.out.print("<<");
}
@Override
public void close() {
System.out.println(">>");
}
@Override
public void print() {
System.out.print(c);
}
}
StringDisplay
public class StringDisplay extends AbstractDisplay{
private String s;
public StringDisplay(String s) {
this.s = s;
}
@Override
public void open() {
System.out.println("========");
}
@Override
public void close() {
System.out.println("========");
}
@Override
public void print() {
System.out.println(s);
}
}
Main
public class Main {
public static void main(String[] args) {
AbstractDisplay abstractDisplay01 = new CharDisplay('a');
AbstractDisplay abstractDisplay02 = new StringDisplay("hello,world!");
abstractDisplay01.display();
abstractDisplay02.display();
}
}
运行结果如下图所示:
模板方法的优缺点
优点:
- 通过把不变的行为挪到一个统一的父类,从而达到去除子类中重复代码的目的
- 子类实现模板父类的某些细节,有助于模板父类的扩展
- 通过一个父类调用子类实现的操作,通过子类扩展增加新的行为,符合“开放-封闭原则”
缺点:
父类和子类紧密联系、共同工作,那么在子类中实现父类的抽象方法时,必须要理解这些抽象方法被调用的时机。在看不到父类源代码的情况下,想要编写出子类是非常困难的。
应用场景
- 多个子类有共有的方法,并且逻辑基本相同
- 重要、复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现
- 重构时,模板方法是一个经常使用的方法,把相同的代码抽取到父类中,然后通过构造函数约束其行为