【Java设计模式】行为型设计模式-模板方法模式(十四)

模板方法模式

  • 模板方法模式又叫模板模式(Template Pattern),属于行为型设计模式。
  • 它在一个抽象类中公开定义了需要执行的方法的模板,它的子类可以按需要重写细节方法,但调用将以抽象类中定义的方式进行。

进一步阐述: 模板方法模式是定义了一个逻辑算法的骨架,而将一些具体的变化的步骤延迟到子类中去实现,使得子类可以不改变一个算法的结构,就可以重定义该算法的某些特定步骤。

模板方法模式包含二种角色:

  • AbstractClass(抽象角色):是一个抽象类,其内部定义了模板方法,也就是定义了整个算法的骨架和组成这个算法的各个步骤(这些步骤有具体的也有抽象的),它具体负责指挥整个算法的流程。
  • ConcreteClass(具体角色):继承了抽象角色,去重写步骤中变化部分的抽象方法。

案例:以泡功夫茶为例,泡功夫茶必须按照严格的步骤进行一步一步去做,最后喝到的才能是清香沁人上等茶品,其具体步骤是:沸水烫壶-->加入茶叶-->头茶洗茶-->养护茶宠-->首道闻香-->泡茶品茶

UML类图:

Client客户端类:

java 复制代码
/**
 * 客户端
 */
public class Client {
​
    public static void main(String[] args) {
        //泡龙井茶
        System.out.println("----------泡龙井茶----------------");
        KungFuTea longjingTea = new LongJingTea();
        longjingTea.makeTea();
​
        //泡铁观音茶
        System.out.println("----------泡铁观音茶----------------");
        KungFuTea tieGuanYinTea = new TieGuanYinTea();
        tieGuanYinTea.makeTea();
​
        //泡碧螺春茶
        System.out.println("----------泡碧螺春茶----------------");
        KungFuTea biLuoChunTea = new BiLuoChunTea();
        biLuoChunTea.makeTea();
    }
}

泡功夫茶的KungFuTea抽象类:

java 复制代码
/**
 * 泡功夫茶的抽象类
 */
public abstract class KungFuTea {
​
    /**
     * 模板方法:用于定义整个算法的骨架,确定好整个算法的步骤顺序
     */
    public void makeTea() {
        wash();
        addTeaLeaves();
        makeFirst();
        maintainTeaUtil();
        smellTea();
        drinkTea();
    }
​
    /**
     * 1、沸水烫壶:"钩子"方法,默认空实现
     */
    protected void wash() {
​
    }
​
    /**
     * 2、加入茶叶
     */
    public abstract void addTeaLeaves();
​
    /**
     * 3、头茶洗茶
     */
    public void makeFirst() {
        System.out.println("加入第一次冲泡的热水,冲泡5-15秒,然后将茶倒入滤杯中。");
    }
​
    /**
     * 4、养护茶宠
     */
    public void maintainTeaUtil() {
        System.out.println("将第一次冲泡滤出来的茶水冲洗茶具。");
    }
​
    /**
     * 5、首道闻香
     */
    public void smellTea() {
        System.out.println("将首道茶水倒入闻香杯,捧杯闻香。");
    }
​
    /**
     * 6、泡茶品茶
     */
    public void drinkTea() {
        System.out.println("将沸水倒入紫砂壶,加盖泡制20秒,倒出后开始品尝。");
    }
}

泡龙井功夫茶LongJingTea类:

java 复制代码
/**
 * 泡龙井功夫茶
 */
public class LongJingTea extends KungFuTea {
    @Override
    public void wash() {
        System.out.println("用预热的泉水加热和冲洗宜兴紫砂茶壶(或盖碗)");
    }
​
    @Override
    public void addTeaLeaves() {
        System.out.println("加入龙井茶茶叶。");
    }
}

泡铁观音功夫茶TieGuanYinTea类:

java 复制代码
/**
 * 泡铁观音功夫茶
 */
public class TieGuanYinTea extends KungFuTea {
    @Override
    public void wash() {
        System.out.println("用预热的泉水加热和冲洗宜兴紫砂茶壶(或盖碗)");
    }
​
    @Override
    public void addTeaLeaves() {
        System.out.println("加入铁观音茶茶叶。");
    }
}

泡碧螺春功夫茶BiLuoChunTea类:

java 复制代码
/**
 * 碧螺春功夫茶类
 */
public class BiLuoChunTea extends KungFuTea {
​
    @Override
    public void addTeaLeaves() {
        System.out.println("加入碧螺春茶茶叶。");
    }
}

总结:

  • 模板方法模式是将一个通用的算法抽离出来存放于一个公用的地方,也就是在父类中,提高代码的可复用性。如果整个算法的骨架需要变更只需要修改父类的模板方法或者已经实现的某些步骤,子类就会继承这些修改。
  • 它既统一了算法,也提供了很大的灵活性。父类的模板方法确保了算法的结构保持不变,同时由子类提供变化步骤的实现。
  • 一般模板方法都加上会final关键字,防止子类重写模板方法去破坏掉整个算法的骨架体系。
  • 将一些可选步骤在抽象角色中设计为空实现即"钩子"方法,一般是用protected去修饰,方便子类去选择是否选用。
  • 每一个不同的细节都需要一个子类实现,导致类的个数增加从而增大系统类的复杂度。

典型运用场景举例: 当实现一个逻辑时,整体步骤是很固定的,但是某些细节步骤是具有很多变化的可能的,那么就可以使用模板方法模式进行设计。例如:jdbc访问数据库、操作各种非关系型数据库。

相关推荐
Lhappy嘻嘻5 小时前
Java IO|File 文件操作 + 字节流 / 字符流完整笔记 + 递归删除文件实战
java·笔记·php
To_OC6 小时前
手写 AI 编程 Agent 的命令执行工具:我被 child_process 坑出来的实战经验
后端·node.js·agent
伊玛目的门徒6 小时前
试用leetcode之典中典 二数之和问题
java·算法·leetcode
逝水无殇8 小时前
C# 异常处理详解
开发语言·后端·c#
懒鸟一枚9 小时前
深入理解 Linux 内存、Swap 交换分区与分页机制的关系
java·linux·数据库
我命由我1234510 小时前
执行 Gradle 指令报错,无法将“grep”项识别为 cmdlet、函数、脚本文件或可运行程序的名称
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
考虑考虑10 小时前
Sentinel安装
java·后端·微服务
IT_陈寒10 小时前
SpringBoot自动配置失灵?你可能忘了这个关键注解
前端·人工智能·后端
碎碎念_49210 小时前
SpringBoot + Vue 前后端分离从 0 到 1 完整环境配置流程
vue.js·spring boot·后端
逝水无殇11 小时前
C# 文件的输入与输出详解
开发语言·数据库·后端·c#