设计模式--模板方法模式(Template Method Pattern)
一、什么是模板方法模式(Template Method Pattern)
模板方法模式(Template Method Pattern)是一种行为型设计模式,它定义了一个算法的骨架,将一些步骤的实现延迟到子类中。模板方法模式允许在不改变算法的结构的情况下,通过在子类中重写特定步骤的具体实现,来改变算法的部分行为。
模板方法模式通常包括以下几个角色:
- 抽象类(Abstract Class):定义了一个模板方法,其中包含了算法的骨架,包括一系列步骤的调用顺序和约定。这些步骤可以是具体的方法,也可以是抽象的,留给子类实现。
- 具体子类(Concrete Subclasses):实现了抽象类中定义的抽象方法,以提供具体步骤的实现,从而完成整个算法。
模板方法模式的主要优点包括:
- 代码重用性:通过将算法的公共部分放在抽象类中,可以避免在每个具体子类中重复编写相同的代码。
- 灵活性:可以通过子类的不同实现来定制和扩展算法的部分行为,而不需要修改算法的整体结构。
- 易于维护:将算法分解成一系列步骤,每个步骤都有明确的功能,使得代码更易于理解和维护。
模板方法模式常见于许多框架和库中,例如:
- 在GUI框架中,窗口和对话框的创建过程通常遵循模板方法模式。
- 数据库连接和操作的过程也可以使用模板方法模式来定义通用的连接和断开操作,具体数据库的实现由子类完成。
总之,模板方法模式通过定义算法骨架和具体步骤的分离,实现了代码重用、定制和易维护的目标。
二、模板方法模式的现实应用场景
一个现实中常见的应用模板方法模式的场景是咖啡和茶的制作过程。这两种饮料的制作过程有一些共同的步骤,但在其中的某些步骤上有所不同,因此可以使用模板方法模式来实现这种共同和变化的结构。
假设我们有一个名为"Beverage"的抽象类,它定义了制作饮料的模板方法。在这个模板方法中,包含了制作饮料的通用步骤,如加热水、冲泡、倒入杯中等。然后,我们有两个具体子类,“Coffee"和"Tea”,它们分别实现了抽象类中的特定步骤,以适应不同的饮料。
以下是示例代码:
// 抽象类
abstract class Beverage {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");}
}// 具体子类 Coffee
class Coffee extends Beverage {void brew() {System.out.println("Dripping coffee through filter");}void addCondiments() {System.out.println("Adding sugar and milk");}
}// 具体子类 Tea
class Tea extends Beverage {void brew() {System.out.println("Steeping the tea");}void addCondiments() {System.out.println("Adding lemon");}
}
在这个例子中,抽象类"Beverage"定义了模板方法prepareBeverage(),它包含了制作饮料的通用步骤。具体子类"Coffee"和"Tea"分别实现了不同的步骤,以制作咖啡和茶。这样,我们可以保留通用的制作流程,并在具体子类中实现特定的细节步骤。
通过使用模板方法模式,我们可以避免在每个具体子类中重复编写相同的制作步骤,同时也能很方便地扩展和修改制作流程,而不必改变整体结构。这个例子展示了模板方法模式在实际应用中的使用。
三、使用模板方法模式需要注意的问题
在使用模板方法模式时,需要注意一些问题,以确保正确地应用该模式并避免潜在的陷阱:
- 过度复杂化:过度使用模板方法模式可能导致代码过于复杂,因为模板方法模式的设计理念是将通用的流程提取出来,但有时可能会引入不必要的抽象和层级,导致代码难以理解和维护。
- 灵活性和变化:模板方法模式主要用于处理固定的算法结构,如果算法的变化点过多,可能会导致模板方法模式不够灵活,需要频繁修改模板和子类。
- 继承限制:使用模板方法模式意味着子类必须遵循父类定义的流程,如果不满足这种流程,可能需要强行适应,从而破坏了设计的灵活性。
- 破坏开放封闭原则:如果在模板方法中增加新的步骤,需要同时修改所有子类,这可能违反了开放封闭原则,即对扩展开放,对修改封闭。
- 复杂的继承结构:随着项目的发展,可能会出现多级继承结构,导致难以维护和理解。
- 不易于单元测试:由于模板方法的实际行为由多个子类共同决定,因此在单元测试时可能需要考虑更多的因素。
- 违反单一职责原则:在抽象类中包含了多个步骤的实现,可能导致抽象类功能过于复杂,违反了单一职责原则。
为了更好地应用模板方法模式,可以考虑以下策略:
- 谨慎使用:只在确实有共同流程的算法中使用模板方法模式,避免过度设计。
- 合理抽象:确保抽象类和具体子类之间的关系适当,并且继承结构不会过于复杂。
- 钩子方法:通过在抽象类中添加钩子方法,允许子类对流程进行部分修改。
- 策略模式替代:在一些变化较大的情况下,可以考虑使用策略模式,将算法的不同部分作为策略进行组合。
相关文章:

设计模式--模板方法模式(Template Method Pattern)
一、什么是模板方法模式(Template Method Pattern) 模板方法模式(Template Method Pattern)是一种行为型设计模式,它定义了一个算法的骨架,将一些步骤的实现延迟到子类中。模板方法模式允许在不改变算法的…...
linux 权限管理命令
权限管理命令 权限的查看及含义 可以使用ls -l来查看每个文件或目录的权限,一共有十位 ls -ls--------------------------------------------------------------------rw-------. 1 root root 946 Feb 14 16:13 anaconda-ks.cfgdrwxr-xr-x. 2 root root 4096 Feb…...

c++ qt--线程(一)(第八部分)
c qt–线程(一)(第八部分) 一.进程(Process) 在任务管理器中的进程页下,可以看到进程,任务管理器将进程分为了三类,应用、后台进程、window进程 应用: 打开…...
参数初始化方法
梯度消失与梯度爆炸 考虑一个 3 层的全连接网络。 H 1 X W 1 H{1}X \times W{1} H1XW1, H 2 H 1 W 2 H{2}H{1} \times W{2} H2H1W2, O u t H 2 W 3 OutH{2} \times W_{3} OutH2W3 其中第 2 层的权重梯度如下: Δ W 2 ∂ L o s s …...

Go的基础运行方式和打包
目录 基础运行方式导入路径 打包技巧相关知识点 基础运行方式 // 文件名可以不是main,但包名和入口函数比如是main // main.go package main // 导入包的时候可以直接导入,也可以导入后指定包名, import ("fmt"godemo "githu…...

Deepin 图形化部署 Hadoop Single Node Cluster
Deepin 图形化部署 Hadoop Single Node Cluster 升级操作系统和软件 快捷键 ctrlaltt 打开控制台窗口 更新 apt 源 sudo apt update更新 系统和软件 sudo apt -y dist-upgrade升级后建议重启 开启ssh服务 打开资源管理器 进入系统盘 找到 etc 目录 在系统盘的 etc 目录上 右键…...

23款奔驰GLS400升级柏林之声音响系统,体验不一样的感觉
Burmester 环绕立体声音响系统–为每位乘员打造令人印象深刻的音质13个高性能扬声器、总功率为590瓦的9声道数字信号处理器(DSP)放大器以及放大器/扬声器系统专为车辆配置,打造出一流的Burmester之音。必要时还可进一步提升令人印象深刻的听觉体验。声音环绕功能能够…...
Vue的map()方法和filter()方法的使用
map() map():方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值 案例: const data res.map(item > item.id); const data res.map(item > return item.id); const data res.map(item > { name: item.name, id…...
qt创建临时文件
1、临时文件系统 在 Linux 系统中,创建临时文件系统很简单,执行如下指令即可: mount -t tmpfs -o size1024m tmpfs /mnt/tmp 挂载成功后,在 /mnt/tmp 这个挂载点下创建的所有文件都将会是临时文件, 也就是说:当电脑关…...

Element——table排序,上移下移功能。及按钮上一条下一条功能
需求:table排序,可操作排序上移下移功能。判断第一行上移禁用和最后一行下移禁用,排序根据后端返回的字段 <el-table:data"tableData"style"width: 100%"><el-table-column type"index" label"序…...

无涯教程-Android - Linear Layout函数
Android LinearLayout是一个视图组,该视图组将垂直或水平的所有子级对齐。 Linear Layout - 属性 以下是LinearLayout特有的重要属性- Sr.NoAttribute & 描述1 android:id 这是唯一标识布局的ID。 2 android:baselineAligned 此值必须是布尔值,为…...

ELK安装、部署、调试(六) logstash的安装和配置
1.介绍 Logstash是具有实时流水线能力的开源的数据收集引擎。Logstash可以动态统一不同来源的数据,并将数据标准化到您选择的目标输出。它提供了大量插件,可帮助我们解析,丰富,转换和缓冲任何类型的数据。 管道(Logs…...
【Spring Security】UserDetails 接口介绍
文章目录 UserDetails 的作用UserDetails 接口中各个方法详解 UserDetails 的作用 UserDetails 在 Spring Security 框架中主要担任获取用户信息的接口,通过该接口就能拿到用户的信息和验证用户的信息,这些信息在下面的方法中会有讲述。 UserDetails 接…...

C# Linq源码分析之Take(四)
概要 本文主要对Take的优化方法进行源码分析,分析Take在配合Select,Where等常用的Linq扩展方法使用时候,如何实现优化处理。 本文涉及到Select, Where和Take和三个方法的源码分析,其中Select, Where, Take更详尽的源码分析&…...
Python 和 C++ 使用细节差别
1. 循环中的可迭代对象长度 1. 循环中的可迭代对象长度 C 中,for循环中写明a.size(),每次循环这个值是重新计算的; # include “iostream” # include <vector> using namespace std;int main() {vector<int> a(10);int cnt 0…...

在Ubuntu Linux系统上安装RabbitMQ服务并解决公网远程访问问题
文章目录 前言1.安装erlang 语言2.安装rabbitMQ3. 内网穿透3.1 安装cpolar内网穿透(支持一键自动安装脚本)3.2 创建HTTP隧道 4. 公网远程连接5.固定公网TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址 前言 RabbitMQ是一个在 AMQP(高级消息队列协议)基…...

葫芦娃自动预约-公众号代挂
效果 #小程序://航旅黔购/1nkYlNRVzm0Gg9x #小程序://贵旅优品/7zz6mtnSVgDfyqa #小程序://新联惠购/ibFdsuhWqIbczEd #小程序://贵盐黔品/u2TgExCUdkavrFe #小程序://空港乐购/ANkOOdqEeo71kah #小程序://遵航出山/ZkR7DQy1raoPxKD #小程序://乐旅商城/Ip5cgpJ7TLmRrWF #小程序…...

ESP32应用教程(0)— PMW3901MB光流传感器
文章目录 前言 1 传感器介绍 1.1 关键特征 1.2 关键参数 2 硬件概述 2.1 信号引脚 2.2 参考电路图 3 寄存器 3.1 寄存器列表 3.2 性能优化寄存器 4 代码说明 4.1 结构体说明 4.2 编译说明 5 波形分析 前言 本文介绍了在 ESP32 DEVKIT V1 开发板上开发 PMW3901MB…...

docker部署nginx,部署springboot项目,并实现访问
一、先部署springboot项目 1、安装docker: yum install docker -y 2、启动docker: service docker start 重启: service docker restart 3、查看版本: docker -v 4、使设置docker.service生效(路径:…...

十五、模板方法模式
一、什么是模板方法模式 模板方法(Template Method)模式的定义如下:定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。 模板方法模式包含以…...

第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...

SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
比较数据迁移后MySQL数据库和OceanBase数据仓库中的表
设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...

windows系统MySQL安装文档
概览:本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容,为学习者提供全面的操作指导。关键要点包括: 解压 :下载完成后解压压缩包,得到MySQL 8.…...

9-Oracle 23 ai Vector Search 特性 知识准备
很多小伙伴是不是参加了 免费认证课程(限时至2025/5/15) Oracle AI Vector Search 1Z0-184-25考试,都顺利拿到certified了没。 各行各业的AI 大模型的到来,传统的数据库中的SQL还能不能打,结构化和非结构的话数据如何和…...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...

【堆垛策略】设计方法
堆垛策略的设计是积木堆叠系统的核心,直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法,涵盖基础规则、优化算法和容错机制: 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则: 大尺寸/重量积木在下…...