1. TemplateMethod模式
处理流程在父类中被定义,具体处理交给了子类。这同时反应了抽象类的意义,即在抽象类阶段确定处理的流程,具体的处理内容由子类决定。
1.1 拓展
在理解类层次时,从子类的角度来看,你可能会关注以下几点:
- 在子类中可以使用父类定义的方法
- 可以通过在子类中增加方法以实现新的功能
- 在子类中重写父类的方法可以改变程序的行为
从父类的角度来看,在父类中我们声明了抽象方法,希望子类去具体实现,即:
- 期待子类去实现抽象方法
- 要求子类去实现抽象方法
这意味着,子类具体实现在父类中声明的抽象方法的责任,被称为“子类责任”。
1.2 TemplateMethod模式的类图
登场的角色:
- AbstractClass(抽象类)
AbstractClass中实现了模板方法,并声明了在模板方法中所要使用到的抽象方法。这些抽象方法由其子类ConcreteClass角色实现。 - ConcreteClass(具体类)
负责实现AbstractClass角色中定义的抽象方法。
可以看到子类与父类是紧密联系、共同工作的,子类在实现抽象方法时必须清楚知道父类是如果工作的。
1.3 示例程序
类一览表:
名字 | 说明 |
---|---|
AbstractDisplay | 定义了并实现了模板方法 |
CharDisplay | 套用模板的具体类,实现了父类的抽象方法 |
StringDisplay | 套用模板的另一个具体类,实现了父类的抽象方法 |
Main | 测试类 |
uml类图(只显示了继承关系)
uml类图
AbstractDisplay类
package xin.ajay.templatemethod.framework;
package xin.ajay.templatemethod.framework;
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();
}
}
CharDisplay类
package xin.ajay.templatemethod.impl;
import xin.ajay.templatemethod.framework.AbstractDisplay;
public class CharDisplay extends AbstractDisplay {
private char c;
public CharDisplay(char c){
this.c = c;
}
@Override
public void open() {
System.out.print("open<<");
}
@Override
public void print() {
System.out.print(c);
}
@Override
public void close() {
System.out.println(">>close");
}
}
StringDisplay类
package xin.ajay.templatemethod.impl;
import xin.ajay.templatemethod.framework.AbstractDisplay;
public class StringDisplay extends AbstractDisplay {
private String msg;
private int width;
public StringDisplay(String msg){
this.msg = msg;
this.width = msg.getBytes().length;
}
@Override
public void open() {
printLine();
}
private void printLine() {
System.out.print("+");
for (int i = 0; i < width; i++) {
System.out.print("-");
}
System.out.println("+");
}
@Override
public void print() {
System.out.print("|");
System.out.print(msg);
System.out.println("|");
}
@Override
public void close() {
printLine();
}
}
Main类
package xin.ajay.templatemethod.impl;
import xin.ajay.templatemethod.framework.AbstractDisplay;
public class Main {
public static void main(String[] args) {
AbstractDisplay d1 = new CharDisplay('a');
AbstractDisplay d2 = new StringDisplay("hello,hi");
d1.display();
d2.display();
}
}
鸣谢:
GoF《设计模式》和结城浩的《图解设计模式》