模板方法模式(继承的优雅使用)
目录
前言
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模型,采用粒子群算法,在保证电动汽车用户出行需求的前提下,为了使工作区域电动汽车尽可能多的消…...
<QT基础(4)>QLabel使用笔记
Label 前面的文章里面把QLabel批量引入ScrollArea作为预览窗口,这篇把图像填充到QLable的PixelMap展示指定图像。 参数设置 设置QLabel的大小格式 QWidget* widget new QWidget; widget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); widget->…...
2016年认证杯SPSSPRO杯数学建模C题(第二阶段)如何有效的抑制校园霸凌事件的发生全过程文档及程序
2016年认证杯SPSSPRO杯数学建模 C题 如何有效的抑制校园霸凌事件的发生 原题再现: 近年来,我国发生的多起校园霸凌事件在媒体的报道下引发了许多国人的关注。霸凌事件对学生身体和精神上的影响是极为严重而长远的,因此对于这些情况我们应该…...
前端理论总结(css3)——css优化的方法
1:首推的是合并css文件,如果页面加载10个css文件,每个文件1k,那么也要比只加载一个100k的css文件慢 2:减少css嵌套,最好不要套三层以上 3:不要在ID选择器前面进行嵌套,ID本来就是唯一…...
项目立项管理
目录 1.概述 2.项目建议与立项申请 3.项目可行性研究 3.1.内容 3.2.初步可行性研究 3.3.详细可行性研究 4.项目评估与决策 5.总结 1.概述 本文的目录结构参考了《信息系统项目管理师教程(第四版)》。 项目立项管理是一项全面评估准备投资工程的多…...
QT的学习
代码练习 完成一个使用qss的登陆窗口界面。 使用手动连接,将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中,在自定义的槽函数中调用关闭函数 将登录按钮使用qt5版本的连接到自定义的槽函数中,在槽函数中判断ui界面上输入的账号是否…...
redis在docker安装并启动流程
1、启动server docker run -d -p 6379:6379 --name redis01 redis:7.2.4以上命令,每次启动新的Redis容器,数据会丢失。 我们需要挂载数据文件,在宿主机上面,这样就可以持久化数据. 2、挂载数据文件(可根据需求选择…...
Spring高频面试题
(一些来源于GitCode AI) 什么是Spring框架? Spring是一个开源的Java平台,它简化了企业级应用的开发。它提供了IOC(Inversion of Control)/DI(Dependency Injection)容器,…...
Qt篇——Qt无法翻译tr()里面的字符串
最近遇到使用Qt语言家翻译功能时,ui界面中的中文都能够翻译成英文,但是tr("测试")这种动态设置给控件的中文,无法翻译(lang_English.ts文件中的翻译已经正确添加了tr()字符串的翻译)。 上网搜了很多资料&am…...
农村分散式生活污水分质处理及循环利用技术指南
标准已完成意见征集: 本文件给出了农村分散式生活污水分质处理及循环利用的总则、污水收集、污水分质处理、资源化利用、利用模式、运维管理等的指导。 本文件适用于农村分散式生活污水分质处理及循环利用的设施新建、扩建和改建工程的设计、施工与运维。 注:本文件…...
深圳区块链交易所app系统开发,撮合交易系统开发
随着区块链技术的迅速发展和数字资产市场的蓬勃发展,区块链交易所成为了数字资产交易的核心场所之一。在这个快速发展的领域中,区块链交易所App系统的开发和撮合交易系统的建设至关重要。本文将探讨区块链交易所App系统开发及撮合交易系统的重要性&#…...
做电影网站怎么降低内存/域名注册优惠
要导入下面这个包就可以了 import android.view.View.OnClickListener;转载于:https://blog.51cto.com/binuu/776045...
为什么做网站网站/免费建立个人网站
中国清华大学(Tsinghua University)的研究人员最近发表一种基于石墨烯纳米结构的锂金属电极材料,可用于抑制锂金属电池中的枝晶生长,进一步提升其电化学性能。 “目前广泛使用的锂离子电池越来越难以满足可携式电子产品和电动车(EV)日益增加的储能要求。…...
湛江网站制作推荐/统计站老站长推荐草莓
机房收费系统总结(思想) 第一次机房收费系统算是接近尾声了,可是我们真正的软件设计之路才刚刚拉开序幕 仔细回想整个做系统的过程,技术先不说,最最令人吃惊的是整个过程将性格,心理,习惯上的种种弊病展现的淋漓尽致.机房收费系统都可以叫心理测试系统了,不过结果只有自己知道…...
php网站链接支付宝/怎样在网上做宣传
<!--实现搜索结果的关键词变色标注的程序四月 5th, 2006 在搜索得到的文本中,从第一个关键词出现的前50个字开始显示,把关键词替换为红色,这比单纯的用replace得到的显示结果更人性化一些,因为用replace的话一旦关键词出现在文…...
下载网站软件免费安装/湖人排名最新
科目二总结 注意!!! 以下情况根据具体情况调节 1.左倒车入库 直行,车头碰住黄线的时候朝左打死,人对准直角朝右回半圈,目视前方,车正了朝右回到初始角度,w朝上 倒车:挂倒挡,后视镜的角碰到黄…...
wordpress 迅影网/营销型网站的类型
来源:牛客网 有如下函数定义,执行结果正确的是? def dec(f): n 3 def wrapper(*args,**kw): return f(*args,**kw) * n return wrapper dec def foo(n): return n * 2 A foo(2) 12 B foo(3) 12 C foo(2) 6 D foo(3) 6...