一、前言
常见的设计模式有23种,我们不得不提到模板方法设计模式,这是一种在软件开发中广泛使用的行为型设计模式之一。
二、模板方式是什么
全称是模板方法设计模式。
模板模式是一种行为设计模式。它的实现思路是,创建一个 模板方法 method,在该模板类中定义一些基本方法供模板方法 method 调用,这些基本方法通常是 protected 修饰的,因为它并不需要对外提供访问。模板方法 method 定义了一个算法的执行步骤,或者说能够提供一种默认的实现,这些实现概括一部分子类或者全部子类的共同部分(说白了就是概括了所有子类的共同特性,并且自己实现了它)。
看到上面的 UML 图,理清下思路:一个最基本的模板方法模式中,你需要创建一个抽象类和一个具体的实现类,从上图可以看到在抽象类中持有一个模板方法和一些基本方法,而子类只需要对这些基本方法进行实现即可,子类并不需要对模板方法进行实现,因为抽象类已经实现好了。
白话讲就是:创建一个抽象类并在里面定义一些方法,有的抽象类本身已经实现,实现方法的复用,有的需要子类去实现提高拓展性。
三、模板方法的原理
模板方法的原理可以简单概括如下:
- 定义算法骨架:在抽象基类中定义一个模板方法,该方法包含了算法的整体流程,通常由一系列步骤组成。这些步骤可以是抽象方法、具体方法或空方法(钩子方法)。
- 子类定制实现:子类继承基类,并实现其中的抽象方法,以提供算法的具体实现。子类可以根据需要定制算法的某些步骤,而不必修改整个算法的结构。
- 模板方法的调用:在客户端代码中,通过调用抽象基类的模板方法来启动算法。模板方法按照定义的流程调用了各个步骤,以及可能的具体方法或钩子方法。
总之,通过这种方式,模板方法设计模式实现了方法的复用,可以更好去拓展,同时将算法的整体结构清晰的展现在一个方法中,使得代码易于理解和维护。
四、项目实战
假设提供一种造房子的算法。算法的步骤就是模拟造房子的过程:建地基、建支撑,最后添加墙和窗户。
最重要的一点就是不能改变此建造过程(也就是我们不能修改或者重写模板方法的意思),比如不可能在没用地基的时候就开始建造窗户吧!如果可以,那简直是胡扯!这个例子中,我们就创建了一个模板方法,将使用不同的方法完成对房子的建造。
1、HouseTemplate 模板类
为了确保子类不能重写(override)这个模板方法,应当使用 final。
HouseTemplate(这个类对应上面 UML 图的 AbstractClass)
public abstract class HouseTemplate {// 这是我们的模板方法,子类不能重写public final void buildHouse() {// 第一步:建造地基buildFoundation();// 第二步:建造支撑buildPillars();// 第三步:建造墙buildWalls();// 第四步:建造窗户buildWindows();System.out.println("房子建造好了");}protected void buildFoundation() {System.out.println("建筑基础用水泥、铁棒和沙子");}// 被子类实现的方法protected abstract void buildPillars();protected abstract void buildWalls();// 这个步骤可以默认实现,原文是 private 修饰,那么就是我规定死啦,这个步骤只能这样实现了。// 但为了易拓展,还是 protected 好点protected void buildWindows() {System.out.println("建造玻璃窗");}}
2、WoodenHouse 实现类
public class WoodenHouse extends HouseTemplate {/*** 建造支撑*/@Overrideprotected void buildPillars() {System.out.println("建造木质涂料建筑支撑");}/*** 建造墙*/@Overrideprotected void buildWalls() {System.out.println("建造木墙");}
}
3、GlassHouse 实现类
public class GlassHouse extends HouseTemplate {/*** 建造支撑*/@Overrideprotected void buildPillars() {System.out.println("建造带有玻璃涂层的建筑支撑");}/*** 建造墙*/@Overrideprotected void buildWalls() {System.out.println("建筑玻璃墙");}}
4、Controller 层,使用模板方法
@PostMapping("/test")public String test() {// 创建一个模板,子类由 WoodenHouse 实现HouseTemplate houseTemplate = new WoodenHouse();// 调用模板方法houseTemplate.buildHouse();System.out.println("-------------------分隔符------------------");// 创建一个模板,子类由 GlassHouse 实现houseTemplate = new GlassHouse();// 调用模板方法houseTemplate.buildHouse();return "success!";}
5、调用接口 localhost:8080/house/test
建筑基础用水泥、铁棒和沙子
建造木质涂料建筑支撑
建造木墙
建造玻璃窗
房子建造好了
-------------------分隔符------------------
建筑基础用水泥、铁棒和沙子
建造带有玻璃涂层的建筑支撑
建筑玻璃墙
建造玻璃窗
房子建造好了
五、模板方法设计模式的特点
- 模板方法不能被子类重写,可用 final 修饰。
- 一个模板方法有确定的步骤组成,这些步骤可以被不同的子类实现,也可以自己实现。
六、模板方法设计模式应用场景
- 对于一个业务方法步骤固定,但这些步骤可以有不同的实现情况下
七、参考文档
谈一谈我对‘模板方法’设计模式的理解(Template)