当前位置: 首页 > news >正文

行为型设计模式——模板方法模式

学习难度:⭐ ,比较常用

模板方法模式

在面向对象程序设计过程中,程序员常常会遇到这种情况:设计一个系统时知道了算法所需的关键步骤,而且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知,或者说某些步骤的实现与具体的环境相关。例如拿泡茶这件事来说,可以分为4个步骤,第一步洗茶具,第二步烧开水,第三步放入茶叶并根据不同的茶叶泡不同的时间,第四步品茶。以上的一二四步都是一样的,只有第三步不一样,因此可以将一二四步具体实现好,即模板方法。第三步则是用户自己需要实现的方法,即抽象方法。模板方法的定义: 定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。

模板方法(Template Method)模式包含以下主要角色:

  • 抽象类(Abstract Class):负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。

    • 模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法。

    • 基本方法:是实现算法各个步骤的方法,是模板方法的组成部分。基本方法又可以分为三种:

      • 抽象方法(Abstract Method) :一个抽象方法由抽象类声明、由其具体子类实现。

      • 具体方法(Concrete Method) :一个具体方法由一个抽象类或具体类声明并实现,其子类可以进行覆盖也可以直接继承。

      • 钩子方法(Hook Method) :在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种。

        一般钩子方法是用于判断的逻辑方法,这类方法名一般为isXxx,返回值类型为boolean类型。

  • 具体子类(Concrete Class):实现抽象类中所定义的抽象方法和钩子方法,它们是一个顶级逻辑的组成步骤。

案例

【例】炒菜

炒菜的某些步骤是固定的,分为开启灶台、倒油、炒菜、倒调料品、起锅共五个步骤。假设炒菜和倒调料品两个步骤不一样,其他都一样,现通过模板方法模式来用代码模拟。类图如下:

在这里插入图片描述

代码

编写抽象模板类,其中开炉灶、倒油、起锅都是固定的方法,而炒菜和放调味品则是根据不同的菜品而不同的,而cook()方法则是一个将上述步骤组合调用的一个方法,使用final修饰不可被重写,如下:

// 烹饪抽象类
public abstract class AbstractCook {// 做菜很多步骤都一样的,只是关键步骤不一样,// 因此,相同步骤作为模板实现好,不同的自己实现private String food;public AbstractCook(String food){this.food = food;}public void openStove(){//1. 开启灶台是相同步骤System.out.println("打开灶台,将锅烧热");}public void pourOil(){//2. 倒油是相同步骤System.out.println("油倒入锅中,并烧热");}//3. 翻炒时间和手法不一样public abstract void fry();//4. 不同菜的调味品不一样public abstract void pourSauce();//5. 出锅是一样的public void takeFood(){System.out.println("将炒好的"+food+"盛入餐盘中");}// final 修饰不被继承public final void cook(){openStove();pourOil();fry();pourSauce();takeFood();}
}

然后具体的菜品的制作继承上述模板类,其中共同的步骤就不用重新写了,只需要重写自己的炒菜和放调味品的具体方法

// 炒贵州黄牛肉类
public class CookBeef extends AbstractCook{public CookBeef() {super("贵州黄牛肉");}@Overridepublic void fry() {System.out.println("牛肉下锅,总共炒10分钟,每个30秒翻一下");}@Overridepublic void pourSauce() {System.out.println("放盐和味精,其他放酱油、蒜末、辣椒、葱花去腥提鲜");}
}// 炒青菜类
public class CookVegetable extends AbstractCook{public CookVegetable() {super("青菜");}@Overridepublic void fry() {System.out.println("蔬菜下锅,总共炒2分钟,每个5秒翻一下");}@Overridepublic void pourSauce() {System.out.println("放盐和味精,其他放耗油即可");}
}

客户端测试类:

public class Main {public static void main(String[] args) {// 炒牛肉CookBeef cookBeef = new CookBeef();cookBeef.cook();System.out.println("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");// 炒青菜CookVegetable cookVegetable = new CookVegetable();cookVegetable.cook();}
}

输出结果:

打开灶台,将锅烧热
油倒入锅中,并烧热
牛肉下锅,总共炒10分钟,每个30秒翻一下
放盐和味精,其他放酱油、蒜末、辣椒、葱花去腥提鲜
将炒好的贵州黄牛肉盛入餐盘中
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
打开灶台,将锅烧热
油倒入锅中,并烧热
蔬菜下锅,总共炒2分钟,每个5秒翻一下
放盐和味精,其他放耗油即可
将炒好的青菜盛入餐盘中

优点

  • 提高代码复用性

    将相同部分的代码放在抽象的父类中,而将不同的代码放入不同的子类中。

  • 实现了反向控制

    通过一个父类调用其子类的操作,通过对子类的具体实现扩展不同的行为,实现了反向控制 ,并符合“开闭原则”。

缺点

  • 对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象。
  • 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。

适用场景

  • 算法的整体步骤很固定,但其中个别部分易变时,这时候可以使用模板方法模式,将容易变的部分抽象出来,供子类实现。
  • 需要通过子类来决定父类算法中某个步骤是否执行,实现子类对父类的反向控制。

相关文章:

行为型设计模式——模板方法模式

学习难度:⭐ ,比较常用 模板方法模式 在面向对象程序设计过程中,程序员常常会遇到这种情况:设计一个系统时知道了算法所需的关键步骤,而且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知&#xff0…...

曲面上偏移命令的查找

今天学习老王的SW绘图时,遇到一个命令找不到,查询了一会终于找到了这个命令,防止自己忘记,特此记录一下,这个命令就是“曲面上偏移”,网上好多的教程都是错误的,实际上这个命令没有在曲面里面&a…...

世邦spon IP网络对讲广播系统任意文件上传漏洞

产品介绍 世邦通信IP网络对讲广播系统采用领先的IPAudio™技术,将音频信号以数据包形式在局域网和广域网上进行传送,是一套纯数字传输系统。 漏洞描述 spon IP网络对讲广播系统存在任意文件上传漏洞,攻击者可以通过构造特殊请求包上传恶意后门文件,从…...

mp4文件全部转换为mp3

问题 今天突发奇想,想把mp4视频转换为mp3来收听,于是想到了ffmpeg工具 步骤 安装ffmpeg环境 要在 Windows 上配置 FFmpeg 环境,你可以按照以下步骤进行操作: 下载 FFmpeg: 首先,你需要下载 FFmpeg 的 W…...

深信服技术认证“SCSA-S”划重点:逻辑漏洞

为帮助大家更加系统化地学习网络安全知识,以及更高效地通过深信服安全服务认证工程师考核,深信服特别推出“SCSA-S认证备考秘笈”共十期内容,“考试重点”内容框架,帮助大家快速get重点知识~ 划重点来啦 *点击图片放大展示 深信服…...

Linux grep命令教程:强大的文本搜索工具(附案例详解和注意事项)

Linux grep命令介绍 grep (Global Regular Expression Print)命令用来在文件中查找包含或者不包含某个字符串的行,它是强大的文本搜索工具,并可以使用正则表达式进行搜索。当你需要在文件或者多个文件中搜寻特定信息时,grep就显得无比重要啦…...

网络安全的威胁PPT

建议的PPT免费模板网站:http://www.51pptmoban.com/ppt/ 此PPT模板下载地址:https://file.51pptmoban.com/d/file/2023/03/20/1ae84aa8a9b666d2103f19be20249b38.zip 内容截图:...

CUDA驱动深度学习发展 - 技术全解与实战

全面介绍CUDA与pytorch cuda实战 关注TechLead,分享AI全维度知识。作者拥有10年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕,复旦机器人智能实验室成员,阿里云认证的资深架构师,项目管理专业人士&…...

如何做用户分层和标签体系

“活动作了一场接一场,简直要累死了,拉进来的客户也没有多少,投入产出完全不成比例,怎么办?“ “有那么多注册用户,但是GMV怎么才这么点,他们怎么不买啊,难道都是羊毛党?…...

Vue+Element Ui实现el-table自定义表头下拉选择表头筛选

用vueelement ui开发管理系统时,使用el-table做表格,当表格列过多的时候,想要做成可选表头的,实现表格列的筛选显示,效果如下: 代码文件结构: 废话不多说,直接上代码: 第…...

使用Java连接MongoDB (6.0.12) 报错

报错: Exception in thread "main" com.mongodb.MongoCommandException: Command failed with error 352: Unsupported OP_QUERY command: create. 上图中“The client driver may require an upgrade”说明了“客户端驱动需要进行升级”,解…...

数学建模day16-预测模型

本讲首先将介绍灰色预测模型,然后将简要介绍神经网络在数据预测中的应用,在本讲的最 后,我将谈谈清风大佬对于数据预测的一些看法。 注:本文源于数学建模学习交流相关公众号观看学习视频后所作 目录 灰色系统 GM(1,1)…...

Vue3响应式系统(一)

一、副作用函数。 副作用函数指的是会产生副作用的函数。例如:effect函数会直接或间接影响其他函数的执行,这时我们便说effect函数产生了副作用。 function effect(){document.body.innerText hello vue3 } 再例如: //全局变量let val 2f…...

MStart | MStart开发与学习

MStart | MStart开发与学习 1.学习 1.MStart |开机LOG显示异常排查及调整...

GoZero微服务个人探索之路(一)Etcd:context deadline exceeded原因探究及解决

产生错误原因就是与etcd交互时候需要指定: 证书文件的路径 客户端证书文件的路径 客户端密钥文件的路径 (同时这貌似是强制默认就需要指定了) 但我们怎么知道这三个文件路径呢,如下方法 1. 找到etcd的配置文件,里…...

C语言从入门到实战——结构体与位段

结构体与位段 前言一、结构体类型的声明1.1 结构体1.1.1 结构的声明1.1.2 结构体变量的创建和初始化 1.2 结构的特殊声明1.3 结构的自引用 二、 结构体内存对齐2.1 对齐规则2.2 为什么存在内存对齐2.3 修改默认对齐数 三、结构体传参四、 结构体实现位段4.1 什么是位段4.2 位段…...

java如何修改windows计算机本地日期和时间?

本文教程,主要介绍,在java中如何修改windows计算机本地日期和时间。 目录 一、程序代码 二、运行结果 一、程序代码 package com;import java.io.IOException;/**** Roc-xb*/ public class ChangeSystemDate {public static void main(String[] args)…...

flink中的row类型详解

在Apache Flink中,Row 是一个通用的数据结构,用于表示一行数据。它是 Flink Table API 和 Flink DataSet API 中的基本数据类型之一。Row 可以看作是一个类似于元组的结构,其中包含按顺序排列的字段。 Row 的字段可以是各种基本数据类型&…...

漏洞复现-Yearning front 任意文件读取漏洞(附漏洞检测脚本)

免责声明 文章中涉及的漏洞均已修复,敏感信息均已做打码处理,文章仅做经验分享用途,切勿当真,未授权的攻击属于非法行为!文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…...

K8S中SC、PV、PVC的理解

存储类(StorageClass)定义了持久卷声明(PersistentVolumeClaim)所需的属性和行为,而持久卷(PersistentVolume)是实际的存储资源,持久卷声明(PersistentVolumeClaim&#…...

Codex入门19-数据库操作(解放双手:用自然语言写SQL、建表和数据迁移)

Codex入门19-数据库操作(解放双手:用自然语言写SQL、建表和数据迁移) 📌 文章简介:写 SQL 是后端开发的日常,但复杂的 JOIN、子查询、窗口函数总让人头疼。本文教你用 Codex CLI 实现:自然语言直接生成 CREATE TABLE、复杂 SQL 查询、数据库迁移脚本(Prisma/Knex/Alem…...

Agent Harness 系列:为什么你的 Agent 演示很顺、上线就崩?

导读: 同样的模型,换一套外围基础设施,排名从第 30 开外直接冲到第 5——没有改动任何模型权重,没有换更贵的 API。这不是玄学,这是 Agent Harness 的威力。本文是三篇系列的第一篇,从"为什么需要 Har…...

给Llama-3-8B-Instruct加个‘垫片’:手把手教你安全添加Pad Token并微调(附完整代码)

为Llama-3-8B-Instruct安全添加Pad Token的工程实践指南当你在微调Llama-3-8B-Instruct时,是否遇到过这样的困扰:模型没有提供Pad Token,导致数据处理和训练过程中出现各种不便?这个问题看似简单,实则暗藏玄机。本文将…...

等保2.0三级Linux服务器合规基线重建实战指南

1. 为什么等保2.0整改不是“打补丁”,而是重装操作系统级的系统工程你刚接手一台跑了三年的CentOS 7服务器,业务跑得稳,监控没告警,运维日志里连个WARNING都少见——但等保测评报告第一页就写着:“操作系统未满足等保2…...

李飞飞团队新作ESI-Bench:具身智能的ImageNet来了!

点击下方卡片,关注“CVer”公众号AI/CV重磅干货,第一时间送达【具身智能】微信群成立!大家快扫码加入具身星球,将获得:最新具身智能技术和项目、❤️ 从入门到精通的学习路线、🤖 具身智能招聘(实习/校招/社…...

ncmdumpGUI:三步解密网易云音乐NCM文件,实现音乐自由播放

ncmdumpGUI:三步解密网易云音乐NCM文件,实现音乐自由播放 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换,Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 你是否在网易云音乐下载了心爱…...

面霸AI · 用 Multi-Agent 让面试模拟卷出天际

🧑‍💻 博主介绍 & 诚邀关注 作者:专注于 Java、Python、前端开发的技术博主 | 全网粉丝 30 万 在校期间协助导师完成毕业设计课题分类、论文格式初审及代码整理工作;工作后持续分享毕设思路,助力毕业生顺利完成…...

机器学习可复现性危机:八大维度解析与工程实践指南

1. 项目概述:为什么我们需要重新审视机器学习的“可复现性”?如果你在机器学习领域摸爬滚打过几年,大概率遇到过这样的场景:兴冲冲地打开一篇顶会论文的GitHub仓库,按照README的指示安装依赖、运行脚本,结果…...

Taotoken 的 API Key 分级管理与审计日志功能在安全合规中的实际价值

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 Taotoken 的 API Key 分级管理与审计日志功能在安全合规中的实际价值 在企业级应用开发中,将大模型能力集成到业务系统…...

仅剩最后47套!《ChatGPT脑筋急转弯生成军规手册》PDF+127个经A/B测试验证的高互动Prompt模板(含儿童/职场/银发三版适配)

更多请点击: https://kaifayun.com 第一章:ChatGPT脑筋急转弯生成的核心价值与认知重构 传统脑筋急转弯创作依赖人类经验直觉,存在耗时长、多样性受限、语义陷阱设计不精准等瓶颈。而基于大语言模型的自动化生成,不仅突破了创意密…...