3 Template Method模式
3.1 Template Method模式
在父类中定义处理流程的框架,在子类中具体实现的模式称为Template Method模式。
3.2 示例程序
示例程序的类图

类的一览表
| 名字 | 说明 |
|---|---|
| AbstractDisplay | 只实现了display方法的抽象类 |
| CharDisplay | 实现了open print close方法的类 |
| StringDisplay | 实现了open print close方法的类 |
| Main | 测试程序 |
AbstractDisplay
是一个抽象类,只实现了display方法。调用其他方法,实际处理被交给了子类。
public abstract class AbstractDisplay { // 抽象类AbstractDisplaypublic abstract void open(); // 交给子类去实现的抽象方法(1) openpublic abstract void print(); // 交给子类去实现的抽象方法(2) printpublic abstract void close(); // 交给子类去实现的抽象方法(3) closepublic final void display() { // 本抽象类中实现的display方法open(); // 首先打开…for (int i = 0; i < 5; i++) { // 循环调用5次printprint();}close(); // …最后关闭。这就是display方法所实现的功能}}
public class CharDisplay extends AbstractDisplay { // CharDisplay是AbstractDisplay的子类private char ch; // 需要显示的字符public CharDisplay(char ch) { // 构造函数中接收的字符被this.ch = ch; // 保存在字段中}@Overridepublic void open() { // 在父类中是抽象方法,此处重写该方法System.out.print("<<"); // 显示开始字符"<<"}@Overridepublic void print() { // 同样地重写print方法。该方法会在display中被重复调用System.out.print(ch); // 显示保存在字段ch中的字符}@Overridepublic void close() { // 同样地重写close方法System.out.println(">>"); // 显示结束字符">>"}}public class StringDisplay extends AbstractDisplay { // StringDisplay也是AbstractDisplay的子类private String string; // 需要显示的字符串private int width; // 以字节为单位计算出的字符串长度public StringDisplay(String string) { // 构造函数中接收的字符串被this.string = string; // 保存在字段中this.width = string.getBytes().length; // 同时将字符串的字节长度也保存在字段中,以供后面使用}@Overridepublic void open() { // 重写的open方法printLine(); // 调用该类的printLine方法画线}@Overridepublic void print() { // print方法System.out.println("|" + string + "|"); // 给保存在字段中的字符串前后分别加上"|"并显示出来}@Overridepublic void close() { // close方法printLine(); // 与open方法一样,调用printLine方法画线}private void printLine() { // 被open和close方法调用。由于可见性是private,因此只能在本类中被调用System.out.print("+"); // 显示表示方框的角的"+"for (int i = 0; i < width; i++) { // 显示width个"-"System.out.print("-"); // 组成方框的边框}System.out.println("+"); // /显示表示方框的角的"+"}}
3.3 Template Method模式中的角色
在Template Method模式中的角色。
- AbstractClass(抽象类) 该角色不仅负责实现模板方法,还负责声明在模板方法中使用到的抽象方法。这些抽象方法由子类ConcreteClass角色负责实现。
- ConcreteClass(具体类) 该角色负责具体AbstractClass角色中定义的抽象方法。

3.4 扩展思路的要点
可以使逻辑处理通用化
使用模板模式的优点是,由于再父类的模板方法中编写了算法,因此无需子类中在编写算法。
父类和子类之间的协作
在模板模式中,父类和子类是密切联系、共同工作的。因此,在子类中实现父类中声明的抽象方法时,必须要理解理解抽象方法被调用的时机。在看不到父类源码的情况下,想要编写出子类是非常困难的。
父类与子类的一致性
无论在父类类型的变量中保存哪个子类的实例,程序都可以正常工作,这种原则称为里氏替换原则(LSP)。
3.6 延伸阅读:类的层次与抽象类
父类对子类的要求
在理解类的层次时,通常是站在子类的角度进行思考的。也就说,很容易着眼与以下几点。
- 在子类中可以使用父类中定义的方法。
- 可以通过在子类中增加方法以实现新的功能。
- 在子类中重写父类的方法可以改变程序的行为
站在父类的角度思考。在父类中,我们声明了抽象方法,而将方法的实现交给了子类。换而言之,就程序而言,声明抽象是希望达到以下目的。
- 期待子类去实现抽象方法
- 要求子类去实现抽象方法
也就是说,子类具有实现在父类中所声明的抽象方法的责任,这种责任被称为“子类责任”。
4 Factory Method模式(将实例的生成交给子类)
4.1 Factory Method
在Factory Method模式中,父类决定实例的生成方式,但并不决定所要生成具体的类,具体的处理全部交给子类负责。这样就可以将生成实例的框架和实际负责生成实例的类解耦。
4.2 示例程序

Product类和Factory类属于framework包。这两个类组成了生成实例的框架。<br />IDCard类和IDCardFactory类负责实际加工处理,它们属于idcard包。
- 生成实例的框架(framework包)
- 加工处理(idcard包)
public abstract class Factory {public final Product create(String owner) {Product p = createProduct(owner);registerProduct(p);return p;}protected abstract Product createProduct(String owner);protected abstract void registerProduct(Product product);}public abstract class Product {public abstract void use();}
public class IDCardFactory extends Factory {private List owners = new ArrayList();@Overrideprotected Product createProduct(String owner) {return new IDCard(owner);}@Overrideprotected void registerProduct(Product product) {owners.add(((IDCard) product).getOwner());}public List getOwners() {return owners;}}public class IDCard extends Product {private String owner;IDCard(String owner) {System.out.println("制作" + owner + "的ID卡。");this.owner = owner;}@Overridepublic void use() {System.out.println("使用" + owner + "的ID卡。");}public String getOwner() {return owner;}}
4.3 Factory Method模式中的角色

类图中的角色
- Product(产品):Product角色属于框架这一方,是一个抽象类。它定义了Factory Method模式中生成的那些实例所持有的接口,但具体的处理交给ConcreteProduct角色决定。
- Creator(创建者):Creator角色属于框架一方,它是负责生成Product角色的抽象类,但具体的处理则由子类ConcreteCreator角色决定
- ConcreteProduct(具体的产品):属于具体加工一方,它决定了具体的产品。
- ConcreteCreator(具体的创建者):属于具体加工这一方。负责生成具体的产品。
