13、设计模式之模板模式(Template)

news2024/11/24 14:12:30

一、什么是模板模式
模板模式是一种基于继承实现的设计模式,它是行为型的模式。

主要思想是将定义的算法抽象成一组步骤,在抽象类种定义算法的骨架,把具体的操作留给子类来实现。

通俗地说,模板模式就是将某一行为制定一个框架,然后子类填充细节。比如说做菜,流程通常就是洗菜、切菜、炒菜等步骤,那么这个流程就可以看作是一个模板,而具体做什么菜由子类来实现。

二、角色组成

抽象类(Abstract):定义了算法骨架,包含一个或多个抽象方法,这些方法由子类来具体实现。抽象类中通常还包含一个模板方法,用来调用抽象方法和具体方法,控制算法的执行顺序;还可以定义钩子方法,用于在算法中进行条件控制。
具体类(Concrete Class):继承抽象类,实现抽象方法。

三、优缺点
优点:

提高代码复用性:将算法的骨架定义在父类中,子类只需要实现具体的细节部分,减少了代码的重复。
符合开闭原则:在模板模式种,由父类控制子类的执行,通过子类对父类进行扩展增加新的行为,符合“开闭原则”。
提高代码可维护性:模板模式定义了一套固定的模板,便于开发人员理解和修改,易于维护。
缺点:

部分子类可能无法灵活定制:由于模板模式制定的是一个固定的结构,所以某些子类可能无法适用,导致无法实现特定的需求或定制。
类的数量增加:每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。
四、应用场景
4.1 生活场景
写文章:假设我们要写一篇文章,其中包括标题、引言、正文和结论等部分。我们可以将文章的写作过程定义为一个模板,在抽象类中定义写作方法,如先写标题、再写引言、接着写正文,最后写结论。具体类就是每篇文章的实现类,它们可以根据主题和内容的不同来实现对应的部分。这样,每个具体文章类只需要关注自己特定的内容,而写作的步骤则由模板来控制
学习流程:比如学习某门课程的流程,在学习过程中有一些共同的步骤,比如预习、上课、复习做练习等。我们可以定义一个抽象类StudyCourse,在其中定义学习的方法。具体类就是每门具体课程的实现类,它们根据课程内容和学习方式来实现抽象类中的方法。模板方法则是定义在抽象类中的一组方法,用于规定学习的整体流程和一些基本规则。
4.2 java场景

JdbcTemplate:JdbcTemplate提供了一系列的模板方法,如execute、query、update等。开发者可以通过继承JdbcTemplate并实现相应的抽象方法来完成数据库操作的具体实现。
HttpServlet:HttpServlet类是一个抽象类,提供了handleRequest、doGet、doPost等模板方法,用于处理HTTP请求。Servlet开发者可以继承HttpServlet并实现这些方法来处理具体的请求,从而完成一个特定的Servlet实现。
Servlet过滤器:Java Servlet
API中提供了过滤器(Filter)接口,用于对Servlet请求进行拦截和处理。该接口中定义了一个doFilter()方法,该方法是一个模板方法,由子类实现具体的请求拦截和处理方式。

五、代码实现
下面以订外卖为例,解释一下模板模式。假设订外卖的过程包含三个步骤:选择外卖、支付、取外卖、是否打赏,我们可以定义一个OderFood的抽象类,那么选择外卖就可以是抽象方法,需要子类取实现它,支付和取外卖可以定义为具体方法,另外是否打赏为钩子方法,子类可以决定是否对算法的不同进行挂钩,还需要定义一个模板方法,用以控制流程;不同的商家,如KFC、星巴克就是具体类。

5.0 UML类图
在这里插入图片描述
5.1 OrderFood——抽象类(Abstract)

/**
 * 
 * 1.抽象类(Abstract Class):点外卖
 * 包含选择外卖、支付、取外卖三个方法,
 * 其中选择外卖为抽象方法,需要子类实现
 * 支付、取外卖为具体方法
 * 另外是否打赏为钩子方法,子类可以决定是否对算法的不同进行挂钩
 */
public abstract class OrderFood {
 
    //模板方法
    public void order(){
        selectFood();
        pay();
        getFood();
    }
    //选择外卖   抽象方法 由子类实现具体细节
    public abstract void selectFood();
    //是否打赏   钩子方法 可以重写来做条件控制
    public boolean isGiveAward(){
        return false;
    }
    //-------具体方法----------
    public void pay(){
        System.out.println("支付成功,外卖小哥正在快马加鞭~~");
    }
 
    //取外卖
    public void getFood(){
        System.out.println("取到外卖");
        if (isGiveAward()){
            System.out.println("打赏外卖小哥");
        }
    }
}

5.2 具体类(Concrete Class)

/**
 * 
 * 具体类(Concrete Class):星巴克
 */
public class Starbucks extends OrderFood{
 
    //实现父类方法
    @Override
    public void selectFood() {
        System.out.println("一杯抹茶拿铁");
    }
 
    //重写钩子方法,打赏外卖小哥
    @Override
    public boolean isGiveAward(){
        return true;
    }
}
/**
 * 
 * 具体类(Concrete Class):KFC
 */
public class KFC extends OrderFood{
    @Override
    public void selectFood() {
        System.out.println("一份汉堡炸鸡四件套");
    }
}

5.3 testTemplate

/**
 * 
 * 模板模式测试类
 */
@SpringBootTest
public class TestTemplate {
 
    @Test
    void testTemplate(){
        //星巴克(重写了钩子方法,打赏外卖小哥)
        OrderFood orderFood=new Starbucks();
        orderFood.order();
        System.out.println("--------KFC------------");
        //KFC
        OrderFood orderFood1=new KFC();
        orderFood1.order();
    }
}

在这里插入图片描述

六、总结
我们可以把模板看作是一个公共的蓝本,而子类就像是根据这个蓝本来实现自己独特的需求。所以当我们在开发中遇到一些情况,比如多个类共享一些相同的操作,或者说想要控制子类扩展某个算法的一部分功能时,就可以考虑模板模式了。另外,还有以下几个适用场景以做参考:

子类需要扩展算法的部分功能:当需要控制子类对算法的某些步骤进行扩展或修改,同时保持算法骨架不变时,可以使用模板模式。
实现多个算法的不同细节:当需要在不同的场景下使用相同的算法,但是细节实现不同,可以使用模板模式。
需要统一流程的业务:在一些对流程敏感的业务中,例如订餐、下单等,使用模板方法模式可以统一流程,使代码更加简洁和易维护。并且在统一流程的同时,也能保证业务的正确性。

注意事项: 为防止恶意操作,一般模板方法都加上 final 关键词。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1512414.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Selenium操作浏览器,弹出文件选择框,实现自动选定“目标文件”

前言 本文是该专栏的第20篇,后面会持续分享python爬虫干货知识,记得关注。 我们在使用selenium操作目标页面的时候,可能会遇到如下图所示的情景。 在用selenium操作并点击页面元素的时候,会弹出一个文件选择框,需要我们选择目标文件,并点击确认按钮,目标文件才能上传成…

三防手机与普通手机的区别在哪里?

一、三防手机和普通手机主要的区别在于其防护性能,它们是针对不同环境和使用场景设计的。三防手机一般包括防水、防尘和防摔三个方面的特点,而普通手机则往往没有这些特点。 防水性能。三防手机的防水性能通常比普通手机更强大。三防手机可以在一定程度上…

C#四部曲(知识补充)

Unity跨平台原理 .Net相关 只要编写的时候遵循.NET的这些规则,就能在.NET平台下通用 各种源码→根据.NET规范编写→(虚拟机)生成CIL中间码(保存在程序集中)→转成操作系统原代码 跨语言← 跨平台↓ Unity跨平台原理(Mono) c#脚本→MonoC#编…

Stream-JDK8

Stream概念 代码示例 package com.zz.stream;import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.stream.Collectors;/*** 使用Stream流* 找出姓张并且是三个字的名字*/ public class Test {public static void main(Stri…

《向量数据库指南》——Milvus Cloud BYOC:为数据安全而生?

最近,整个硅谷都在关注 OpenAI 和 Anthropic 的动态。先是 Anthropic 发布了 Claude 3,剑指 GPT-4,被媒体认为“打破了 OpenAI 不可战胜的神话”。这也点燃了整个科技圈的热情,纷纷期待 OpenAI 放出 GPT-5 应战。随后(美东时间 3 月 5 日),OpenAI 发布一则官方公告,主题…

Linux认识与学习BASH

Linux认识与学习BASH 认识BASH这个Shellshell是什么系统的合法shell与/etc/shells功能Bash Shell的功能查询命令是否为Bash shell 的内置命令(type)命令的执行与快速编辑按钮 shell的变量功能什么是变量?变量的使用与设置:echo、变量设置规则、unset环境…

1.6数组

一.序言 数组是一组类型相同类型元素的集合,数组的定长的(数组的长度一旦被定义,长度不可改变)。 数组在内存当中是一块连续的空间,可以保存相同类型的多个元素。 二.一维数组 2.1.数组的创建 int arr1[10]; …

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的吸烟检测系统(深度学习+Python代码+PySide6界面+训练数据集)

摘要:本文详细说明了如何利用深度学习开发一个用于监测吸烟行为的系统,并分享了完整的代码实现。该系统采用了先进的YOLOv8算法,同时还使用YOLOv7、YOLOv6、YOLOv5算法,并对它们进行了性能比较,呈现了不同模型的性能指…

bpmn-js系列之Palette

前边写了四篇文章介绍了bpmn.js的基本使用,最近陆续有小伙伴加我催更,感谢对我这个半吊子前端的信任,接着更新bpmn.js的一些高级用法,本篇介绍对左侧工具栏Palette的隐藏和自定义修改 隐藏shape 左侧工具栏Palette有些图标我用不…

NIFI从Oracle11G同步数据到Mysql_亲测可用_解决数据重复_数据跟源表不一致的问题---大数据之Nifi工作笔记0065

首先来看一下整体的流程: 可以看到了用到了上面的这些处理器,然后我们主要看看,这里之前 同步的时候,总是出现重复的数据,奇怪. 比如源表中只有166条数据,但是同步过去以后变成了11万条数据了. ${db.table.name:equals(table1):or(${db.table.name:equals(table2)})} 可以看…

LeetCode169. 多数元素(Java)

给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入:nums [3,2,3] 输出:3 示例 …

C++(3/12)

自己封装一个矩形类(Rect)&#xff0c;拥有私有属性:宽度(width)、高度(height)&#xff0c; 定义公有成员函数: 初始化函数:void init(int w, int h) 更改宽度的函数:set_w(int w) 更改高度的函数:set_h(int h) 输出该矩形的周长和 #include <iostream>using name…

设计模式-行为型模式-模版方法模式

模板方法模式&#xff0c;定义一个操作中的算法的骨架&#xff0c;而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。[DP] 模板方法模式是通过把不变行为搬移到超类&#xff0c;去除子类中的重复代码来体现它的优势。 //首…

MinIO权限提升漏洞CVE-2024-24747详细解决办法

漏洞名称&#xff1a; MinIO权限提升漏洞(CVE-2024-24747) 漏洞简介 2024年2月2日&#xff0c;深瞳漏洞实验室监测到一则MinIO 存在权限提升漏洞的信息&#xff0c;漏洞编号&#xff1a;CVE-2024-24747&#xff0c;漏洞威胁等级&#xff1a;高危。 该漏洞是由于用户创建的访…

【机器学习】样本、特征、标签:构建智能模型的三大基石

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;机器学习 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进…

如何进行专利布局与专利规避

一、专利布局 WHY 专利布局是指企业或个人在科研或生产过程中&#xff0c;为了保护和利用自身的技术成果&#xff0c;通过综合产业、市场和法律等因素&#xff0c;对专利进行有机结合&#xff0c;构建严密高效的专利保护网&#xff0c;最终形成对企业或个人有利的专利组合。 …

前端JavaScript篇之常见事件

目录 JavaScript常见事件click&#xff08;点击&#xff09;mouseover&#xff08;鼠标悬停&#xff09;keydown&#xff08;按键按下&#xff09;load&#xff08;加载&#xff09;submit&#xff08;提交&#xff09; JavaScript常见事件 JavaScript中的事件是指用户与网页元…

Device Tree (二) - dtb格式

dtb作为二进制文件被加载到内存中&#xff0c;然后由内核读取并进行解析&#xff0c;如果对dtb文件的格式不了解&#xff0c;那么在看设备树解析相关的内核代码时将会寸步难行&#xff0c;而阅读源代码才是了解设备树最好的方式&#xff0c;所以&#xff0c;如果需要更透彻的了…

来来来, SAP BTP下使用CAP来生成PostgreSQL应用(一): Node.js篇

前言 SAP云应用程序编程模型(CAP)是一个语言、库和工具框架&#xff0c;用于构建企业级服务和应用程序。它引导开发人员沿着一条经过验证的最佳实践的“黄金之路”前进&#xff0c;并为反复出现的任务提供大量开箱即用的解决方案。 我们这就来看看SAP BTP的CAP到底提供了哪些…

蓝桥杯--日期统计

目录 一、题目 二、解决代码 三、代码分析 ​四、另一种思路 五、关于set文章推荐 一、题目 二、解决代码 #include <bits/stdc.h> using namespace std; int main() {int arr[100] { 5,6,8,6,9,1,6,1,2,4,9,1,9,8,2,3,6,4,7,7,5,9,5,0,3,8,7,5,8,1,5,8,6,1,8,3,0,…