模板方法模式 详解 设计模式
模板方法模式
模板方法模式是一种行为型设计模式,它定义了一个算法的骨架,将一些步骤延迟到子类中实现。这种模式允许子类在不改变算法结构的情况下重新定义算法的某些步骤。
结构
-
抽象类(Abstract Class):负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。其中包含了一些基本操作的步骤,有些步骤由具体子类实现。
-
模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法。
-
基本方法:是实现算法各个步骤的方法,是模板方法的组成部分。基本方法又可以分为三种:
-
抽象方法(Abstract Method) :一个抽象方法由抽象类声明、由其具体子类实现。
-
具体方法(Concrete Method) :一个具体方法由一个抽象类或具体类声明并实现,其子类可以进行覆盖也可以直接继承。
-
钩子方法(Hook Method) :在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种。
一般钩子方法是用于判断的逻辑方法,这类方法名一般为isXxx,返回值类型为boolean类型。
-
-
-
具体子类(Concrete Class):实现抽象类中所定义的抽象方法和钩子方法,它们是一个顶级逻辑的组成步骤。
案例:
你制作一个饮料,步骤是确定的,像烧水; 酿造;倒入杯中,添加调味品。烧水和倒杯是固定的基本操作,酿造和添加调味料这个则是通过具体的情况来定的。
代码实现:
// 抽象类
abstract class Beverage {// 模板方法,定义了算法的骨架public final void prepareBeverage() {boilWater();brew();pourInCup();addCondiments();}// 抽象方法,由子类实现abstract void brew();abstract void addCondiments();// 公共方法,由父类实现void boilWater() {System.out.println("Boiling water");}void pourInCup() {System.out.println("Pouring into cup");}
}// 具体类1
class Coffee extends Beverage {@Overridevoid brew() {System.out.println("Dripping coffee through filter");}@Overridevoid addCondiments() {System.out.println("Adding sugar and milk");}
}// 具体类2
class Tea extends Beverage {@Overridevoid brew() {System.out.println("Steeping the tea");}@Overridevoid addCondiments() {System.out.println("Adding lemon");}
}// 使用示例
public class Main {public static void main(String[] args) {Beverage coffee = new Coffee();coffee.prepareBeverage();System.out.println();Beverage tea = new Tea();tea.prepareBeverage();}
}
注意:为防止恶意操作,一般模板方法都加上 final 关键词。
使用场景:
- 当有一系列算法步骤,其中有一部分是固定的,但是另一部分需要在子类中具体实现时,可以考虑使用模板方法模式。
- 当需要在不同的子类中重用相同的算法框架时,可以使用模板方法模式。
以下是模板方法模式在开发后台管理系统中的使用场景示例:
- 权限管理: 在后台管理系统中,通常需要对不同用户或用户组的权限进行管理。模板方法模式可以定义一个权限管理的骨架,包括权限验证、权限分配等操作,而具体的权限验证和分配操作可以交由子类实现。
- 数据的增删改查: 后台管理系统通常需要对数据进行增加、删除、修改、查询等操作。可以使用模板方法模式定义一个数据操作的骨架,包括数据的验证、数据的持久化等步骤,而具体的数据操作可以由子类实现。
- 数据的导入导出: 后台管理系统可能需要支持数据的导入导出功能,例如从 Excel 文件中导入数据到数据库,或者将数据库中的数据导出为 Excel 文件。可以使用模板方法模式定义一个数据导入导出的骨架,包括数据格式的验证、数据的转换等步骤,而具体的导入导出操作可以由子类实现。
- 日志记录: 后台管理系统通常需要记录用户的操作日志,例如登录日志、操作日志等。可以使用模板方法模式定义一个日志记录的骨架,包括日志的格式化、日志的存储等步骤,而具体的日志记录操作可以由子类实现。
优缺点:
优点:
-
提高代码复用性
将相同部分的代码放在抽象的父类中,而将不同的代码放入不同的子类中。
-
实现了反向控制
通过一个父类调用其子类的操作,通过对子类的具体实现扩展不同的行为,实现了反向控制 ,并符合“开闭原则”。
缺点:
- 对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象。
- 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。
相关文章:
模板方法模式 详解 设计模式
模板方法模式 模板方法模式是一种行为型设计模式,它定义了一个算法的骨架,将一些步骤延迟到子类中实现。这种模式允许子类在不改变算法结构的情况下重新定义算法的某些步骤。 结构 抽象类(Abstract Class):负责给出一…...
Node.js_基础知识(http模块)
网络基础 URL的组成结构:协议名: // 主机名 [:端口号] [/路径] [?查询字符串]协议默认端口: http:80,开发常用端口有 3000、8080、8090、9000https: 443 如果端口被其他程序占用,可以使用 资源监视器 找到占用端口的…...

matlab工具包
matlab安装yalmip和cplex出错 - 知乎 (zhihu.com) Cplex的安装和使用实例-CSDN博客 一条龙教程:Matlab下使用yalmip(工具箱)cplex(求解器)_使用yalmip和cplex求解器进行建模和求解的步骤如下:-CSDN博客 啊啊啊,好开心ÿ…...

UCSF DOCK 分子对接详细案例(01)- rigid, fixed anchor, flexible dock
欢迎浏览我的CSND博客! Blockbuater_drug …点击进入 文章目录 前言一、操作环境二、研究背景三、受体-配体结构文件准备3.1准备文件夹DOCK_workdir, 下载晶体结构3.1.1 来自湿实验的受体配体共晶结构:3.1.2 来自深度学习和语言模型推理预测的蛋白结构&a…...

java基础(4)注解,集合,
注解 什么是注解(Annotation)?注解是放在Java源码的类、方法、字段、参数前的一种特殊“注释” // this is a component: Resource("hello") public class Hello {Injectint n;PostConstructpublic void hello(Param String name…...

基于springboot+vue的大学城水电管理系统(前后端分离)
博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战,欢迎高校老师\讲师\同行交流合作 主要内容:毕业设计(Javaweb项目|小程序|Pyt…...
代码随想录算法训练营第四十六天| 139.单词拆分、卡码网第56题
代码随想录算法训练营第四十六天| 139.单词拆分、卡码网第56题 139.单词拆分卡码网第56题 139.单词拆分 题目链接 文章讲解 class Solution { public:bool wordBreak(string s, vector<string>& wordDict) {int bagSize s.size(), n wordDict.size();vector<boo…...

Redis 在 Linux 系统下安装部署的两种方式详细说明
小伙伴们好,欢迎关注,一起学习,无限进步 Redis安装和配置 1、首先在官网下载好redis-6.0.9.tar.gzhttp://redis.io/ 或者使用 wget 命令下载:wget http://download.redis.io/releases/redis-6.0.9.tar.gz 2、下载使用上传到阿里…...

【茶话数据结构】查找最短路径——Dijkstra算法详解(保姆式详细图解,步步紧逼,保你学会)
💯 博客内容:【茶话数据结构】查找最短路径——Dijkstra算法详解 😀 作 者:陈大大陈 🦉所属专栏:数据结构笔记 🚀 个人简介:一个正在努力学技术的准前端,专注基础和实…...

Webserver解决segmentation fault(core dump)段错问问题
前言 在完成了整个项目后,我用make命令编译了server,当我运行./server文件时,出现了段错误 在大量的代码中找出错因并不是一件容易的事,尤其是对新手程序员来说。而寻找bug的过程就像是侦探调查线索追查凶手一样,我们…...

存储过程基本了解
文章目录 介绍存储过程示例1. 目的2. 输入参数3. 输出参数4. 执行逻辑5. 返回值6. 示例用法7. 注意事项 存储过程的关键字有哪些简单实操 介绍 存储过程是一组预编译的SQL语句,以及流程控制语句,封装在数据库服务器中并可以被重复调用。它们可以接收参数…...
『大模型笔记』RAG应用的12种调优策略指南
RAG应用的12种调优策略指南 文章目录 一. 概要二. 数据索引2.1. 数据清洗2.2. 分块2.3. 嵌入模型2.4. 元数据(或未向量化的数据)2.5. 多索引2.6. 索引算法三. 推理阶段(检索和生成)3.1. 检索参数3.2. 高级检索策略3.3. 重新排序模型3.5. 大语言模型(LLM)...

leedcode刷题--day7(字符串)
23 文章讲解 力扣地址 C class Solution { public:void reverseString(vector<char>& s) {int left 0;int right s.size() - 1; // right 应该初始化为 s.size() - 1while (left < right) {swap(s[left], s[right]); // 直接交换 s[left] 和 s[right] 的值lef…...

【蓝桥杯省赛真题31】python连续正整数之和 中小学青少年组蓝桥杯比赛python编程省赛真题解析
目录 python连续正整数之和 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python连续正整数之和 第十二届蓝桥杯青少年组python比赛省赛真题 …...

【116个】网络安全测试相关面试真题
1、Burpsuite常用的功能是什么? 2、reverse_tcp和bind_tcp的区别? 3、拿到一个待检测的站或给你一个网站,你觉得应该先做什么? 4、你在渗透测试过程中是如何敏感信息收集的? 5、你平时去哪些网站进行学习、挖漏洞提…...

微服务day02-Ribbon负载均衡与Nacos安装与入门
一.Ribbon负载均衡 在上一节中,我们通过在RestTemplte实例中加上了注解 LoadBalanced,表示将来由RestTemplate发起的请求会被Ribbon拦截和处理,实现了访问服务时的负载均衡,那么他是如何实现的呢? 1.1 Ribbon负载均衡的原理 Rib…...

深度学习-神经网络原理
文章目录 神经网络原理1.单层神经网络1.1 回归单层神经网络:线性回归1.2 二分类单层神经网络:sigmoid与阶跃函数 1.3 多分类单层神经网络:softmax回归 神经网络原理 人工神经网络(Artificial Neural Network,ANN&…...
Chat GPT:智能对话的下一步
Chat GPT:智能对话的下一步 介绍 Chat GPT(Generative Pre-trained Transformer)是一种基于Transformer架构的强大对话模型,可以产生自然流畅的回答,并实现人机对话的感觉。本文将探讨Chat GPT在智能对话领域的影响和…...

[数据集][目标检测]鸡蛋破蛋数据集VOC+YOLO格式792张2类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):792 标注数量(xml文件个数):792 标注数量(txt文件个数):792 标注类别…...

RabbitMQ实战学习
RabbitMQ实战学习 文章目录 RabbitMQ实战学习RabbitMQ常用资料1、安装教程2、使用安装包3、常用命令4、验证访问5、代码示例 一、RabbitMQ基本概念1.1. MQ概述1.2 MQ 的优势和劣势1.3 MQ 的优势1. 应用解耦2. 异步提速3. 削峰填谷 1.4 MQ 的劣势1.5 RabbitMQ 基础架构1.6 JMS 二…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...

视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...