模板方法模式(继承的优雅使用)
目录
前言
UML
plantuml
类图
实战代码
AbstractRoutingDataSource
DynamicDataSource
DynamicDataSourceContextHolder
前言
在设计类时,一般优先考虑使用组合来替代继承,能够让程序更加的灵活,但这并不意味着要完全抛弃掉继承。
继承在面向对象编程中用来减少代码冗余和提高复用性,是面向对象编程的一大特性。
只不过在使用继承时必须满足一些条件,才能让我们更好地利用继承,设计出更易维护和扩展的程序。
一般情况下,使用继承需要满足一下两个条件
- 父类所有的属性和方法,都能在子类中适用
- 子类无需复用其他类的方法,并且不会覆写父类已有的方法
模板方法模式是继承使用的优雅示例,一般会设计一个抽象类,在类中定义了一个操作的算法结构,其中一些步骤被设计为抽象方法,需要子类去实现,这些方法被称为模板方法。
模板方法允许子类在不改变算法结构的情况下,重新定义算法的某些特定步骤。
UML
plantuml
@startuml
'https://plantuml.com/class-diagramabstract Template {+ doSomething() : void- step1() : void- step2() : void+ {abstract} step3() : void
}class Concrete {+ step3() : void
}class Client {}Template <|-- ConcreteClient ..> Concrete
@enduml
类图

实战代码
AbstractRoutingDataSource
业务上需要用到动态数据源,可以继承 spring 框架提供的抽象类 AbstractRoutingDataSource 来实现运行中动态切换数据源功能。
初始化动态数据源时,将所有的数据源都保存在 private Map<Object, DataSource> resolvedDataSources 中,每一个数据源对应一个唯一标识。
抽象类定义了决定目标数据源的方法(determineTargetDataSource),用来决定当前操作要使用动态数据源中的哪一个数据源,方法中调用了模板方法(determineCurrentLookupKey),子类只需要实现 determineCurrentLookupKey 这个模板方法,动态地返回数据源唯一标识,便能够实现动态切换数据源了
determineTargetDataSource 与 determineCurrentLookupKey

DynamicDataSource
public class DynamicDataSource extends AbstractRoutingDataSource {public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {super.setDefaultTargetDataSource(defaultTargetDataSource);super.setTargetDataSources(targetDataSources);super.afterPropertiesSet();}@Overrideprotected Object determineCurrentLookupKey() {return DynamicDataSourceContextHolder.getDataSourceType();}
}
DynamicDataSourceContextHolder
public class DynamicDataSourceContextHolder {/*** 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本,* 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。*/private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();/*** 设置数据源变量* @param dataSourceType*/public static void setDataSourceType(String dataSourceType){System.out.printf("切换到{%s}数据源", dataSourceType);CONTEXT_HOLDER.set(dataSourceType);}/*** 获取数据源变量* @return*/public static String getDataSourceType(){return CONTEXT_HOLDER.get();}/*** 清空数据源变量*/public static void clearDataSourceType(){CONTEXT_HOLDER.remove();}
}相关文章:
模板方法模式(继承的优雅使用)
目录 前言 UML plantuml 类图 实战代码 AbstractRoutingDataSource DynamicDataSource DynamicDataSourceContextHolder 前言 在设计类时,一般优先考虑使用组合来替代继承,能够让程序更加的灵活,但这并不意味着要完全抛弃掉继承。 …...
百度智能云千帆,产业创新新引擎
本文整理自 3 月 21 日百度副总裁谢广军的主题演讲《百度智能云千帆,产业创新新引擎》。 各位领导、来宾、媒体朋友们,大家上午好。很高兴今天在石景山首钢园,和大家一起沟通和探讨大模型的发展趋势,以及百度最近一段时间的思考和…...
Python下载cuda包失败后到成功(方便使用GPU加速运算,显著提高代码运行速度)
一、查询自己电脑上的cuda版本方法: 1.在windows的cmd里查询显卡cuda的版本号,命令行输入:nvidia-smi 2.在NVIDIA控制面板上寻找自己电脑上cuda的版本 二、安装支持的cuda的python cupy库 因为我的电脑上为cuda11.4,所以使用cuda114,不同的版…...
【Flink】Flink 处理函数之基本处理函数(一)
1. 处理函数介绍 流处理API,无论是基本的转换、聚合、还是复杂的窗口操作,都是基于DataStream进行转换的,所以统称为DataStreamAPI,这是Flink编程的核心。 但其实Flink为了更强大的表现力和易用性,Flink本身提供了多…...
【Java - 框架 - Lombok】(2) SpringBoot整合Lombok完成日志的创建使用 - 快速上手;
"SpringBoot"整合"Lombok"完成日志的创建使用 - 快速上手; 环境 “Java"版本"1.8.0_202”;“Lombok"版本"1.18.20”;“Spring Boot"版本"2.5.9”;“Windows 11 专业版_22621…...
linux 系统安装php 8.0.2
1. 安装包准备 https://www.php.net/distributions/php-8.0.22.tar.gz 我下载到 /usr/local/src 这个目录了 cd /usr/local/srcwget https://www.php.net/distributions/php-8.0.22.tar.gz 2. tar 解压 然后进到解压的文件夹 tar -zxvf php-8.0.22.tar.gz cd php-8.0.2…...
你管这破玩意叫网络
你是一台电脑,你的名字叫 A 很久很久之前,你不与任何其他电脑相连接,孤苦伶仃。 直到有一天,你希望与另一台电脑 B 建立通信,于是你们各开了一个网口,用一根网线连接了起来。 用一根网线连接起来怎么就能…...
系统开发实训小组作业week5 —— 用例描述与分析
目录 1、电影管理 1.1、 用例描述 1.2、 活动图 1.3、 界面元素 1.4、 功能 2、用户管理 2.1、 用例描述 2.2、 活动图 2.3、 界面元素 2.4、 功能 1、电影管理 1.1、 用例描述 用例号 UC009-01 用例名称 电影管理 用例描述 管理员实现对电影信息、座位数量、价…...
C语言例4-35:鸡翁一,值钱五;鸡母一,值钱三;鸡雏三,值钱一。百钱买百鸡、问鸡翁、鸡母和鸡雏各几何?
方法一: 代码如下: //鸡翁一,值钱五;鸡母一,值钱三;鸡雏三,值钱一。百钱买百鸡、问鸡翁、鸡母和鸡雏各几何? //方法一: #include<stdio.h> int main(void) {int x…...
Leetcode 167. 两数之和 II - 输入有序数组
给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列 ,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] ,则 1 < index1 < index2 < numbers.…...
Java实体类之间的转换
一.为什么要转换实体类 通常在后端开发中经常不直接返回实体Entity类,经过处理转换返回前端,前端提交过来的对象也需要经过转换Entity实体才做存储。 二.怎么转换 使用的BeanUtils.copyProperties方法虽然可以实现转换,但是比较粗暴&#…...
ESCTF-Web赛题WP
0x01-初次见面-怦然心动:your name? 随便输入一个字 根据提示可以看到 我们需要看源代码 直接 搜索 secret 关键字或者 ESCTF flag ESCTF{K1t0_iS_S0_HAPPy} 0x02-小k的请求 更安全的传参 post 参数为ESCTF 值为 love 自己的ip 同时还有个要求 是需要从度娘转过来 https://www…...
某物登录表单加密
之前分析过某物h5的以及小程序的搜索接口,就是一个aes,秘钥不固定,表单里把秘钥以及密文一起发过去,服务器解密后再把数据加密返回,客户端解密展示到页面上. 这期是关于app的登录,密码登录 声明 本文章中所有内容仅供学习交流使用,不用于其他任何目的,…...
2024java面试题
题目:反转一个单链表描述:给定一个单链表的头节点,将其反转,返回反转后的链表的头节点。 题目:合并两个有序链表描述:给定两个有序链表的头节点,将它们合并成一个有序链表,返回合并…...
FebHost:什么是哈萨克斯坦.KZ域名?
哈萨克斯坦,作为中亚地区重要的一员,其国家域名”.kz”正成为这个独立国家在网络世界中的代表。作为一个经济快速发展的国家,哈萨克斯坦的互联网基础设施和网络应用也在蓬勃发展。而.kz域名正是哈萨克斯坦网络身份的重要体现。 作为注册和管理.kz域名的主要机构,哈…...
python(一)网络爬取
在爬取网页信息时,需要注意网页爬虫规范文件robots.txt eg:csdn的爬虫规范文件 csdn.net/robots.txt User-agent: 下面的Disallow规则适用于所有爬虫(即所有用户代理)。星号*是一个通配符,表示“所有”。 Disallow&…...
港大新工作 HiGPT:一个模型,任意关系类型 !
论文标题: HiGPT: Heterogeneous Graph Language Model 论文链接: https://arxiv.org/abs/2402.16024 代码链接: https://github.com/HKUDS/HiGPT 项目网站: https://higpt-hku.github.io/ 1. 导读 异质图在各种领域…...
Git版本管理使用手册 - 5 - Git的.ignore文件语法
Git的.ignore文件 1.使用 .ignore文件可以忽略指定文件的版本控制。 2.语法: (1)#开头表示注释 (2)!开头表示不忽略匹配文件 (3)* 表示除/外,任何字符串 (4)?表示除/外,任何一个字符 (5)/ 如果模式的结尾有分割符/&am…...
使用Spring Cloud Gateway构建API网关,实现路由、过滤、流量控制等功能。
使用Spring Cloud Gateway构建API网关,实现路由、过滤、流量控制等功能。 使用Spring Cloud Gateway可以轻松地构建API网关,实现路由、过滤、流量控制等功能。下面是一个简单的示例,演示如何在Spring Boot应用程序中集成Spring Cloud Gatewa…...
Matlab|电动汽车充放电V2G模型
目录 1 主要内容 1.1 模型背景 1.2 目标函数 1.3 约束条件 2 部分代码 3 效果图 4 下载链接 1 主要内容 本程序主要建立电动汽车充放电V2G模型,采用粒子群算法,在保证电动汽车用户出行需求的前提下,为了使工作区域电动汽车尽可能多的消…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
实战三:开发网页端界面完成黑白视频转为彩色视频
一、需求描述 设计一个简单的视频上色应用,用户可以通过网页界面上传黑白视频,系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观,不需要了解技术细节。 效果图 二、实现思路 总体思路: 用户通过Gradio界面上…...
