模板方法是一种行为设计模式,它用于创建一个方法存根和推迟一些步骤执行的子类。模板方法定义的步骤来执行一个算法,它可以提供一种可能是共同的所有或一些子类的默认的实现。
让我们来了解这种模式有一个例子,假设我们要提供一个算法来盖房子。该步骤需要执行盖房是 - 建筑物地基,建筑物的支柱,建筑墙体和窗户。最重要的一点是,我们不能改变执行的顺序,因为我们不能建立在建地基前去建造窗户。因此,在这种情况下,我们可以创建将使用不同的方法来构建房子的模板方法。
现在所有类型的房子的地基都是是相同的,不论是它的一个木制的房子或是玻璃房子。因此,我们可以提供基本实现,如果子类需要重写此方法,它们可以重新实现内容,但大多是很常见的房屋所有类型。
模版方法抽象类:
由于我们想要子类实现该方法,所以我们创建基类为抽象类;
HouseTemplate.java
package com.journaldev.design.template; public abstract class HouseTemplate { //模版方法, final 拒绝子类重写 public final void buildHouse(){ buildFoundation(); buildPillars(); buildWalls(); buildWindows(); System.out.println("House is built."); } //默认实现 private void buildWindows() { System.out.println("Building Glass Windows"); } //子类必须实现方法 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; 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.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(); } }
注意这里调用调用基类的模板的方法,并根据不同的实施步骤,使用了从基类中继承,一些在子类中的重新实现方法。
输出结果:
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.
实现要点:
1,模板方法应包括某些步骤的顺序是固定的,对于某些方法,由不同子类具体去实现,模板方法应该是最终是固定的。
2, 大多数时候,子类调用从父类,但在模板模式的方法,父类的模板方法调用方法的子类,这是被称为好莱坞原则 - “不给我们打电话,我们会打电话给你。”
3,在基类中的方法默认的实现被称为钩,他们的目的是由子类重写,如果你想使一些方法不能被覆盖,你可以使用final修饰,例如,在我们的例子中,我们可以 使用final buildFoundation()修饰,因为我们不想子类重写它。
jdk中模版模式应用:
所有非抽象方法:
java.io.InputStream, java.io.OutputStream, java.io.Reader and java.io.Writer.
java.util.AbstractList, java.util.AbstractSet and java.util.AbstractMap.