读书笔记 仅供参考
什么是 Template Method 模式
模板方法模式是带有模板功能功能的模式,组成模板的方法被定义在父类中,方法都是抽象方法,唯一知道的就是父类如何调用这些方法。实现抽象方法的是子类,在不同的子类中有不同的实现处理,但是处理的流程都按照父类所定义的进行。
父类中定义处理流程的框架,在子类中实现具体处理。
这个模式基本上就是实现继承,主要是在父类中多了一个定义处理流程的方法。
UML
父类比子类多了一个 templateMethod 方法,这个方法需要使用 final 修饰符,只需要在父类中定义就可以了。
例子
例子很简单,父类定义了三个抽象方法和一个模板方法,模板方法中按一定顺序调用了三个抽象方法。两个子类分别实现了三个抽象方法,然后通过模板方法调用。
代码:
https://github.com/wujunyucg/DesignPattern/tree/master/src/chapter02/templateMethod
父类
public abstract class AbstractDisplay {
public abstract void open();
public abstract void print();
public abstract void close();
public final void dispaly() {
open();
for(int i = 0; i < 5; i++) {
print();
}
close();
}
}
第一种子类实现
public class CharDisplay extends AbstractDisplay {
private char ch;
public CharDisplay(char ch) {
this.ch = ch;
}
@Override
public void open() {
System.out.print("<<");
}
@Override
public void print() {
System.out.print(ch);
}
@Override
public void close() {
System.out.println(">>");
}
}
第二种子类实现
public class StringDisplay extends AbstractDisplay {
private String string;
private int width;
public StringDisplay(String string) {
this.string = string;
this.width = string.getBytes().length;
}
@Override
public void open() {
printLine();
}
@Override
public void print() {
System.out.println("|" + string + "|");
}
@Override
public void close() {
printLine();
}
private void printLine() {
System.out.print("+");
for(int i = 0; i < width; i++) {
System.out.print("-");
}
System.out.println("+");
}
}
Main 类进行测试
public class Main {
public static void main(String[] args) {
AbstractDisplay d1 = new CharDisplay('H');
AbstractDisplay d2 = new StringDisplay("Hello, world.");
AbstractDisplay d3 = new StringDisplay("你好,世界");
d1.dispaly();
d2.dispaly();
d3.dispaly();
}
}
效果
优缺点
优点
- 如果在模板方法中出现了错误,只需要修改父类即可,如果只是在子类中通过拷贝来编写的模板方法,就需要修改所有子类。
- 符合里氏替换原则。
缺点
- 如果看不到父类的源码,编写子类很困难
- 如何划分很困难,很难判断哪些是父类实现,哪些是子类实现
相关设计模式
Factory Method 模式
将 Template Method 模式用于生成实例的一个例子
Strategy 模式
在 Template Method 模式中,是使用继承改变程序的行为。
而在 Strategy 模式中,使用委托改变程序的行为,并且不是改变部分程序的行为,而是替换整个算法。