1.模板方法(Template Method)模式的定义
2.模板方法模式的优缺点
优点:
缺点:
3.模板方法模式主要角色
3.1 抽象类(Abstract Class):负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。这些方法的定义如下:
3.1.1 模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法。
3.1.2 基本方法:是整个算法中的一个步骤,包含以下几种类型:
抽象方法:在抽象类中申明,由具体子类实现。
具体方法:在抽象类中已经实现,在具体子类中可以继承或重写它。
钩子方法:在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种。
3.2 具体子类(Concrete Class):实现抽象类中所定义的抽象方法和钩子方法,它们是一个顶级逻辑的一个组成步骤。
4.模板方法模式的结构图
5.模板方法模式的实现,以房子构建模板为例
package com.lw.designpattern.templatemethod; /** * @Classname HouseTemplate * @Description 定义抽象类(房子构建模板): * 负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。 * @Author lw * @Date 2020-01-14 14:18 */ public abstract class HouseTemplate { /** 房子构建模板名称 */ protected String templateName; protected HouseTemplate(String templateName) { this.templateName = templateName; } /** 模板方法则使用protected修饰,表明其需要在子类中实现 */ /** 构建门 */ protected abstract void buildDoor(); /** 构建窗户 */ protected abstract void buildWindow(); /** 构建墙 */ protected abstract void buildWall(); /** 构建基地 */ protected abstract void buildBase(); /** 构建厕所 */ protected abstract void buildToilet(); /** * 钩子方法:给予授权,判断是否要执行 * * @return boolean */ protected boolean isBuildToilet() { return true; } /** * 基本方法:构建房子。用final修饰,保证其不会被子类修改 */ public final void buildHouse() { buildDoor(); buildWindow(); buildWall(); buildBase(); if (isBuildToilet()) { buildToilet(); } } }
package com.lw.designpattern.templatemethod; /** * @Classname HouseOne * @Description 具体子类房子构建模板one:实现抽象类中所定义的抽象方法和钩子方法 * @Author lw * @Date 2020-01-14 14:37 */ public class HouseOne extends HouseTemplate { /** 是否需要构建厕所标志 */ public boolean isBuildToilet; public HouseOne(String templateName) { super(templateName); } public HouseOne(String templateName, boolean isBuildToilet) { this(templateName); this.isBuildToilet = isBuildToilet; } @Override protected void buildDoor() { System.out.println(templateName +"的门要采用防盗门"); } @Override protected void buildWindow() { System.out.println(templateName + "的窗户要面向北方"); } @Override protected void buildWall() { System.out.println(templateName + "的墙使用大理石建造"); } @Override protected void buildBase() { System.out.println(templateName + "的地基使用钢铁地基"); } @Override protected void buildToilet() { System.out.println(templateName + "的厕所建在东南角"); } @Override protected boolean isBuildToilet() { return isBuildToilet; } }
package com.lw.designpattern.templatemethod; /** * @Classname HouseTwo * @Description 具体子类房子构建模板two:实现抽象类中所定义的抽象方法和钩子方法 * @Author lw * @Date 2020-01-14 14:37 */ public class HouseTwo extends HouseTemplate { public HouseTwo(String templateName) { super(templateName); } @Override protected void buildDoor() { System.out.println(templateName + "的门采用木门"); } @Override protected void buildWindow() { System.out.println(templateName + "的窗户要向南"); } @Override protected void buildWall() { System.out.println(templateName + "的墙使用玻璃制造"); } @Override protected void buildBase() { System.out.println(templateName + "的地基使用花岗岩"); } @Override protected void buildToilet() { System.out.println(templateName + "的厕所建在西北角"); } }
/** * 模板方法模式 */ @Test public void testTemplateMethod() { // 创建房子模板对象 HouseTemplate houseOne = new HouseOne("房子模板one", false); HouseTemplate houseTwo = new HouseTwo("房子模板two"); // 房子构建模板 System.out.println("=== 房子模板one,构建模板 ==="); houseOne.buildHouse(); System.out.println("=== 房子模板two,构建模板 ==="); houseTwo.buildHouse(); }
结果打印
通过执行结果我们可以清晰的看到,通过重写钩子方法自定义了房子模板one不需要构建厕所(fasle)。
6.模板方法模式的应用场景
原文:https://www.cnblogs.com/lwcode6/p/12191728.html