【设计模式系列】模板方法模式
一、什么是模板方法模式
模板方法模式(Template Method Pattern)是一种行为型设计模式,它在父类中定义一个算法的框架,允许子类在不改变算法结构的情况下重写算法的某些特定步骤。这种模式非常适合于那些存在共同行为的类,但具体实现需要根据不同情况定制的场景。
二、模板方法模式的角色
-
抽象类(Abstract Class):
- 定义模板方法和钩子方法。模板方法是一个定义算法骨架的方法,它调用一系列钩子方法来完成具体的操作。
- 模板方法可以是具体方法,也可以是抽象方法,取决于算法框架是否允许子类改变执行顺序。
-
具体类(Concrete Class):
- 实现抽象类中定义的钩子方法,填充算法的特定步骤。
- 具体类可以完全实现钩子方法,也可以再次声明为抽象类,让更具体的子类去实现。
-
钩子方法(Hook Method):
- 抽象类中定义的可以被子类重写的方法,用于在模板方法中定义算法的特定步骤。
- 钩子方法可以是抽象的,也可以提供默认实现。
-
模板方法(Template Method):
- 抽象类中的一个具体方法,定义了算法的骨架,按顺序调用一系列钩子方法。
- 模板方法可以调用其他模板方法,形成一个模板方法的继承体系。
三、模板方法模式的典型应用场景
-
代码复用: 当希望复用某个算法或操作的不同部分时,模板方法模式可以将通用的部分封装在父类中,而将变化的部分留给子类实现。
-
依赖倒置: 当高层模块不应该依赖于低层模块,两者都应该依赖于抽象时,模板方法模式可以在抽象层定义算法框架,具体的实现依赖于子类的具体实现。
四、模板方法模式在ThreadPoolExecutor中的应用
ThreadPoolExecutor
是 Java 并发包中的一个类,它使用模板方法模式来定义线程池的任务执行流程。以下是它如何应用模板方法模式的详细解释:
-
模板方法:
execute(Runnable command)
:这是Executor
接口中的一个方法,ThreadPoolExecutor
实现了这个方法。它是一个模板方法,定义了任务执行的框架。这个方法负责将任务提交给线程池执行,包括任务队列的添加、线程的创建和启动等。
-
钩子方法:
beforeExecute(Thread t, Runnable r)
:在线程执行任务之前调用,可以被子类重写来执行一些准备工作,如资源初始化。afterExecute(Runnable r, Throwable t)
:在线程执行任务之后调用,可以被子类重用来执行一些清理工作,如资源释放。terminated()
:在所有任务执行完毕后调用,可以被子类重用来执行线程池关闭后的清理工作。
-
保护方法:
addWorker(Runnable firstTask, boolean core)
:尝试添加一个新的 worker 线程到线程池,可以是核心线程或非核心线程。runWorker(Worker w)
:执行 worker 线程的任务。
-
拒绝策略:
reject(Runnable r)
:定义了当任务不能被执行时的拒绝策略,如抛出异常或运行任务。
ThreadPoolExecutor
的模板方法模式使用示例:
public class ThreadPoolExecutor extends AbstractExecutorService {// 模板方法public void execute(Runnable command) {if (!addWorker(command, false)) {reject(command);}}// 钩子方法protected void beforeExecute(Thread t, Runnable r) {// 可以被子类重写}protected void afterExecute(Runnable r, Throwable t) {// 可以被子类重写}protected void terminated() {// 可以被子类重写}protected void reject(Runnable r) {// 默认的拒绝策略,可以被子类重写throw new RejectedExecutionException();}// ... 其他方法 ...
}
在 ThreadPoolExecutor
中,execute
方法是模板方法,它定义了任务执行的框架,并调用了 addWorker
和 reject
方法。beforeExecute
、afterExecute
和 terminated
是钩子方法,它们可以被子类重写来添加特定的逻辑。通过这种方式,ThreadPoolExecutor
允许子类在不改变任务执行基本流程的情况下,插入特定的行为。这种设计使得线程池的行为可以灵活地被定制,同时保持了核心执行逻辑的一致性。
相关文章:

【设计模式系列】模板方法模式
一、什么是模板方法模式 模板方法模式(Template Method Pattern)是一种行为型设计模式,它在父类中定义一个算法的框架,允许子类在不改变算法结构的情况下重写算法的某些特定步骤。这种模式非常适合于那些存在共同行为的类&#x…...

java8 Stream流详细API及用法
目录 整理的更全面的API及用法 创建Stream流 中间操作 filter 过滤 map 映射 flatMap 扁平映射 sorted 排序 limit 截断 skip 跳过 distinct 去重 peek 遍历 终端操作 forEach 遍历 forEachOrdered 顺序遍历 min 统计最小值 max 统计最大值 count 统计元素数量 f…...

Redis——持久化
文章目录 Redis持久化Redis的两种持久化的策略定期备份:RDB触发机制rdb的触发时机:手动执行save&bgsave保存测试不手动执行bgsave测试bgsave操作流程测试通过配置,自动生成rdb快照RDB的优缺点 实时备份:AOFAOF是否会影响到red…...

川字结构布局/国字结构布局
1.串字结构布局 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><style&g…...

2013年国赛高教杯数学建模C题古塔的变形解题全过程文档及程序
2013年国赛高教杯数学建模 C题 古塔的变形 由于长时间承受自重、气温、风力等各种作用,偶然还要受地震、飓风的影响,古塔会产生各种变形,诸如倾斜、弯曲、扭曲等。为保护古塔,文物部门需适时对古塔进行观测,了解各种变…...

web 0基础第一节 文本标签
这是一个html文件的基本结构 在vs code 中使用英文的 ! 可快捷设置这样的结构 <!-- --> 是在html写注释的结构 <!DOCTYPE html> <!--标识当前文档类型为html--> <html> …...

Zookeeper快速入门:部署服务、基本概念与操作
文章目录 一、部署服务1.下载与安装2.查看并修改配置文件3.启动 二、基本概念与操作1.节点类型特性总结使用场景示例查看节点查看节点数据 2.文件系统层次结构3.watcher 一、部署服务 1.下载与安装 下载: 一定要下载编译后的文件,后缀为bin.tar.gz w…...

【Sqlite】sqlite内部函数sqlite3_value_text特性
目录 ⚛️1 结论 ☪️2 说明 ☪️3 传入数值转成科学计数法 ♋3.1 只有整数部分 ♏3.2 只有小数部分 ♐3.3 整数小数 ⚛️1 结论 整数(sqlite视为int64)位数 > 20位,sqlite3_value_text 采用科学计数法。否则正常表示。 浮点数(sqlite视为double)的整数部…...
树莓派应用--AI项目实战篇来啦-4.OpenCV读取、写入和显示视频
1. 介绍 视频是由一张一张图片组成的,所以读取视频就相当于读取很多张图片,然后将其连起来cv2.VideoCapture可以捕获摄像头,但是针对树莓派的CSI摄像头调用方式采用了之前介绍的Picamera2 库,所以在调用的时候是有区别的ÿ…...

智能电子后视镜,汽车驾驶更安全,会是一种趋势
相比于传统的后视镜,智能电子后视镜的确有很多的优点。在下雨天和夜晚场景,电子后视镜可以说是表现优秀。 我之前一直以为我们国内是有规定不能使用电子后视镜。没想到,偶然刷到享界S9的视频,这电子后视镜,妥妥的给安排…...

IEC104规约的秘密之九----链路层和应用层
104规约从TCP往上,分成链路层和应用层。 如图,APCI就是链路层,ASDU的就是应用层 我们看到报文都是68打头的,因为应用层报文也要交给链路层发送,链路层增加了开头的6个字节再进行发送。 完全用于链路层的报文每帧都只有…...

最新Prompt预设词指令教程大全ChatGPT、AI智能体(300+预设词应用)
使用指南 直接复制在AI工具助手中使用(提问前) 可以前往已经添加好Prompt预设的AI系统测试使用(可自定义添加使用) SparkAi系统现已支持自定义添加官方GPTs(对专业领域更加专业,支持多模态文档࿰…...

DockerCompose 启动 open-match
背景介绍 open-match是Google和unity联合开源的支持实时多人匹配的框架,已有多家游戏厂商在生产环境使用,官网 https://open-match.dev/site/ 。原本我们使用的是UOS上提供的匹配能力,但是UOS目前不支持自建的Dedicated servers 集群&#x…...

Chainlit集成Dashscope实现语音交互网页对话AI应用
前言 本篇文章讲解和实战,如何使用Chainlit集成Dashscope实现语音交互网页对话AI应用。实现方案是对接阿里云提供的语音识别SenseVoice大模型接口和语音合成CosyVoice大模型接口使用。针对SenseVoice大模型和CosyVoice大模型,阿里巴巴在github提供的有开…...

Canal 扩展篇(阿里开源用于数据同步备份,监控表和表字段(日志))
1.Canal介绍 Canal把自己伪装成从数据库,获取mysql主数据库的日志(binlog)信息,所以要想使用canal就得先开启数据库日志 https://github.com/alibaba/canal Canal 主要用途是基于 MySQL 数据库增量日志解析,提供增量…...

顺序表的定义
一.顺序表的定义 顺序表--用顺序存储的方式实现线性表 顺序存储。把逻辑上相邻的元素存储在物理位置上也相邻的存储单元中,元素之间的关 系由存储单元的邻接关系来体现。 二.顺序表的实现--静态分配 #include<stdio.h> #define MaxSize 10 //定义最大长度 …...

青少年编程能力等级测评CPA C++一级试卷(1)
青少年编程能力等级测评CPA C一级试卷(1) 一、单项选择题(共20题,每题3.5分,共70分) CP1_1_1.在C中,下列变量名正确的是( )。 A.$123 B&#…...

R语言中的plumber介绍
R语言中的plumber介绍 基本用法常用 API 方法1. GET 方法2. POST 方法3. 带路径参数的 GET 方法 使用 R 对数据进行操作处理 JSON 输入和输出运行 API 的其他选项其他功能 plumber 是个强大的 R 包,用于将 R 代码转换为 Web API,通过使用 plumber&#x…...

uniapp 设置 tabbar 的 midButton 按钮
效果展示: 中间的国际化没生效(忽略就行) 示例代码: 然后在 App.vue 中进行监听: <script>export default {onLaunch(e) {// #ifdef APPuni.onTabBarMidButtonTap(()>{console.log("中间按钮点击回调…...

php 生成随机数
记录:随机数抽奖 要求:每次生成3个 1 - 10 之间可重复(或不可重复)的随机数,10次为一轮,每轮要求数字5出现6次、数字4出现3次、…。 提炼需求: 1,可设置最小数、最大数、每次抽奖生成随机数的个数、是否允许重复 2,可设置每轮指定数字的出现次数 3,可设置每轮的抽奖…...

SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...

简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...

如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
4. TypeScript 类型推断与类型组合
一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式,自动确定它们的类型。 这一特性减少了显式类型注解的需要,在保持类型安全的同时简化了代码。通过分析上下文和初始值,TypeSc…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...

解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用
在工业制造领域,无损检测(NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统,以非接触式光学麦克风技术为核心,打破传统检测瓶颈,为半导体、航空航天、汽车制造等行业提供了高灵敏…...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...

nnUNet V2修改网络——暴力替换网络为UNet++
更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...