Java中的模板方法设计模式
模板方法是一种行为设计模式。
模板方法设计模式用于创建方法存根并将某些实现步骤推迟到子类。
模板方法设计模式
模板方法定义了执行算法的步骤,它可以提供默认实现,该实现对于所有或者某些子类可能是通用的。
让我们通过一个示例来了解这种模式,假设我们想提供一种建造房屋的算法。
建造房屋需要执行的步骤是-建造地基,建造支柱,建造墙壁和窗口。
重要的是,我们无法更改执行顺序,因为我们无法在构建基础之前先构建窗口。
因此,在这种情况下,我们可以创建一个模板方法,该方法将使用不同的方法来建造房屋。
现在,建造房屋的基础对于所有类型的房屋都是相同的,无论是木制房屋还是玻璃房屋。
因此,我们可以为此提供基本的实现,如果子类想要覆盖此方法,则它们可以但对于大多数类型的房屋来说却是常见的。
为了确保子类不会覆盖template方法,我们应该将其定型。
模板方法抽象类
由于我们希望某些方法由子类实现,因此我们必须将基类设为抽象类。
HouseTemplate.java
package com.theitroad.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.theitroad.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.theitroad.design.template; 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"); } }
模板方法设计模式客户端
让我们用一个测试程序来测试我们的模板方法模式示例。
HousingClient.java
package com.theitroad.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(); } }
请注意,客户端正在调用基类的模板方法,并且根据不同步骤的实现,它使用基类中的某些方法和子类中的某些方法。
上面程序的输出是:
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.
JDK中的模板方法设计模式
java.io.InputStream,java.io.OutputStream,java.io.Reader和java.io.Writer的所有非抽象方法。
java.util.AbstractList,java.util.AbstractSet和java.util.AbstractMap的所有非抽象方法。
模板方法设计模式要点
模板方法应包含固定顺序的某些步骤,对于某些方法,实现因基类而异。
模板方法应该是最终的。在大多数情况下,子类从超类调用方法,但是在模板模式中,超类模板方法从子类调用方法,这就是好莱坞原则,即"不要叫我们,我们会叫你"。
具有默认实现的基类中的方法称为Hooks,它们打算被子类覆盖,如果您希望某些方法不被覆盖,则可以将它们设置为final,例如,在我们的例子中,我们可以使buildFoundation() final方法,因为如果我们不希望子类覆盖它。