原文链接 作者:Pankaj Kumar 译者:f0tlo <1357654289@qq.com>
模板模式是一种行为设计模式,它的实现思路是,创建一个桩方法,并且定义一些步骤让子类来实现。模板方法定义了一个算法的执行步骤,或者说能够提供一种默认的实现,这种实现概括一部分子类或者全部子类的共同部分。
举一个例子帮助理解,假设提供一种造房子的算法。算法的步骤就是模拟造房子的过程:建地基、建支撑,最后添加墙和窗户 – 1. Fundation,2. Pillars,3. Walls,4. Windows。最重要的一点就是不能改变此建造过程,比如不可能在没用地基的时候就开始建造窗户。这个例子中,我们就创建了一个模板方法 – 将使用不同的方法完成对房子的建造。
为了确保子类不能重写(override)这个模板方法,应当使用final。
模板方法抽象类
因为设计为一些方法的具体实现留待子类中,所以不得不安排基类为一个抽象类
HouseTemple.java
package com.journaldev.design.template;
public abstract class HouseTemplate {
//template method, final so subclasses can't override
public final void buildHouse(){
buildFoundation();
buildPillars();
buildWalls();
buildWindows();
System.out.println("House is built.");
}
//default implementation
private void buildWindows() {
System.out.println("Building Glass Windows");
}
//methods to be implemented by subclasses
public abstract void buildWalls();
public abstract void buildPillars();
private void buildFoundation() {
System.out.println("Building foundation with cement,iron rods and sand");
}
}
buildHouse()是模板方法并定义了在建造房子过程中一系列方法的执行顺序。
WoodenHouse.java
package com.journaldev.design.template;
public class WoodenHouse extends HouseTemplate {
@Override
public void buildWalls() {
System.out.println("Building Wooden Walls");
}
@Override
public void buildPillars() {
System.out.println("Building Pillars with Wood coating");
}
}
此处也应当对其他方法进行重写,但是为了简便,此处没用完成。
GlassHouse.java
package com.journaldev.design.template;</code>
public class GlassHouse extends HouseTemplate {
@Override
public void buildWalls() {
System.out.println("Building Glass Walls");
}
@Override
public void buildPillars() {
System.out.println("Building Pillars with glass coating");
}
}
使用模板方法
用一个测试程序来测试此处已完成的模板方法。
HouseClient.java
package com.journaldev.design.template;
public class HousingClient {
public static void main(String[] args) {
HouseTemplate houseType = new WoodenHouse();
//using template method
houseType.buildHouse();
System.out.println("************");
houseType = new GlassHouse();
houseType.buildHouse();
}
}
注意,client正在调用基类的模板方法并且依赖于不同步骤的实现细节,即这些正在使用的方法,他们一些来着基类另一些来自子类。上述程序的输出:
Building foundation with cement,iron rods and sand
Building Pillars with Wood coating
Building Wooden Walls
Building Glass Windows
House is built.
************
Building foundation with cement,iron rods and sand
Building Pillars with glass coating
Building Glass Walls
Building Glass Windows
House is built.
模板方法的UML图
JDK中模板方法模式的使用
- java.io.InputStream, java.io.OutputStream, java.io.Reader 以及 java.io.Writer 中所有非抽象方法。
- java.util.AbstractList, java.util.AbstractSet 以及 java.util.AbstractMap中所有非抽象方法。
重要提示
- 模板方法应该是由确定的步骤组成。这些步骤的顺序是固定的。基类与子类之间某些方法或者实现可以有所不同。模板方法应该是final的。
- 大多时候,子类的调用的方法是来自于超类。但是在模板模式中,超类的模板方法调用的方法却来至于子类,这就是著名的Hollywood原则-“don’t call us, we’ll call you”。
- 基类方法的默认实现被退化为钩子Hooks的概念,他们被设计在子类中被重写,如果你期望一些方法在子类中不被重写,你可以让他们为final。比如在例子中buildFoundation()方法是final的,因为不希望它在子类中被重写。
这就在java中全部的模板方法模式实现,希望你已经喜欢上它了。
时间: 2024-10-09 05:55:51