模板方法模式(继承的优雅使用)

目录

前言

UML

plantuml

类图

实战代码

AbstractRoutingDataSource

DynamicDataSource

DynamicDataSourceContextHolder


前言

在设计类时,一般优先考虑使用组合来替代继承,能够让程序更加的灵活,但这并不意味着要完全抛弃掉继承。

继承在面向对象编程中用来减少代码冗余和提高复用性,是面向对象编程的一大特性。

只不过在使用继承时必须满足一些条件,才能让我们更好地利用继承,设计出更易维护和扩展的程序。

一般情况下,使用继承需要满足一下两个条件

  1. 父类所有的属性和方法,都能在子类中适用
  2. 子类无需复用其他类的方法,并且不会覆写父类已有的方法

模板方法模式是继承使用的优雅示例,一般会设计一个抽象类,在类中定义了一个操作的算法结构,其中一些步骤被设计为抽象方法,需要子类去实现,这些方法被称为模板方法。

模板方法允许子类在不改变算法结构的情况下,重新定义算法的某些特定步骤。

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();}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/287645.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024/3/26 C++作业

定义一个矩形类&#xff08;Rectangle&#xff09;&#xff0c;包含私有成员&#xff1a;长(length)、宽&#xff08;width&#xff09;, 定义成员函数&#xff1a; 设置长度&#xff1a;void set_l(int l) 设置宽度&#xff1a;void set_w(int w) 获取长度&#xff1a;int…

Python批量提取图像灰度共生矩阵(GLCM)、支持批量处理、任意图像格式

目录 一、介绍 二、实现 1、特征计算 2、批量处理 3、结果 一、介绍 灰度共生矩阵(Grey Level Co-occurrence Matrix)也叫做空间灰度级依赖矩阵(SGLDM),它是一种基于统计的纹理特征提取的方法。 一般包括四个方向&#xff1a; (a,b)(1,0)&#xff0c;像素对是水平的&am…

基于javaweb(springboot+mybatis)生活美食分享平台管理系统设计和实现以及文档报告

基于javaweb(springbootmybatis)生活美食分享平台管理系统设计和实现以及文档报告 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 …

在django中使用kindeditor出现转圈问题

在django中使用kindeditor出现转圈问题 【一】基础检查 【1】前端检查 确保修改了uploadJson的默认地址 该地址需要在路由层有映射关系 确认有加载官方文件 kindeditor-all-min.js确保有传递csrfmiddlewaretoken 或者后端关闭了csrf验证 <textarea name"content&qu…

AXI-Stream——草稿版

参考自哔站&#xff1a;FPGA IP之AXI4-Lite AXI4-Stream_哔哩哔哩_bilibili 信号 传输层级从小到大 包(----------transfer--transfer--------)------delay--------包(----------transfer--transfer--------) TKEEP和TSTRB共同决定了是哪种数据流

Github简单入门教程

文章目录 使用前提查看项目内容查看项目介绍打包下载项目查看项目作者项目搜索复制项目分支项目创建向项目中添加文件对项目进行评论 使用前提 想要使用Github&#xff0c;首先需要学会科学上网&#xff0c;不然用国内的网在正规情况下是无法访问Github滴~ 查看项目内容 打开…

鸿蒙Harmony应用开发—ArkTS-ForEach:循环渲染

ForEach基于数组类型数据执行循环渲染。 说明&#xff1a; 从API version 9开始&#xff0c;该接口支持在ArkTS卡片中使用。 接口描述 ForEach(arr: Array,itemGenerator: (item: Array, index?: number) > void,keyGenerator?: (item: Array, index?: number): string …

批量重命名文件名,一键翻译重命名并复制到指定文件夹,高效整理无烦恼

在信息爆炸的时代&#xff0c;高效、智能的文件管理已成为职场和生活中的必备技能。然而&#xff0c;传统的文件管理方法往往耗时且繁琐。现在&#xff0c;我们带来了一款全新的解决方案&#xff0c;让您可以轻松实现文件的翻译、重命名和复制到指定文件夹&#xff0c;为您的文…

Vue3+.NET6前后端分离式管理后台实战(七)

1&#xff0c;Vue3.NET6前后端分离式管理后台实战(七)已经在订阅号发布有兴趣的可以关注一下&#xff01; 有兴趣的可以关注一下&#xff1a;

基于单片机的智能汽车防盗系统设计

摘要:本文介绍了一种以汽车专用单片机飞思卡尔MC68HC908QT4CPE 作为底层主控芯片,人体远红外热释传感器、防闯入光幕墙及振动传感器作为检测装置的汽车防盗系统。单片机将检测到的防盗传感器开关信号,通过数据分析,系统可以设置布防和解除布防模式,在布防模式下,当检测到…

mysql安装及操作

一、Mysql 1.1 MySQL数据库介绍 1.1.1 什么是数据库DB&#xff1f; DB的全称是database&#xff0c;即数据库的意思。数据库实际上就是一个文件集合&#xff0c;是一个存储数据的仓库&#xff0c;数据库是按照特定的格式把数据存储起来&#xff0c;用户可以对存储的数据进行…

[HackMyVM]靶场Crossbow

kali:192.168.56.104 靶机:192.168.56.136 端口扫描 # nmap 192.168.56.136 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-03-26 22:17 CST Nmap scan report for crossbow.hmv (192.168.56.136) Host is up (0.0057s latency). Not shown: 997 closed tcp…

STM32F103 CubeMX 使用USB生成键盘设备

STM32F103 CubeMX 使用USB生成键盘设备 基础信息HID8个数组各自的功能 生成代码代码编写添加申明信息main 函数编写HID 修改1. 修改报文描述符2 修改 "usbd_hid.h" 中的申明文件 基础信息 软件版本&#xff1a; stm32cubmx&#xff1a;6.2 keil 5 硬件&#xff1a;…

(二)Eureka服务搭建,服务注册,服务发现

1.Eureka注册中心 假如我们的服务提供者user-service部署了多个实例&#xff0c;如图&#xff1a; 存在几个问题&#xff1a; order-service在发起远程调用的时候&#xff0c;该如何得知user-service实例的ip地址和端口&#xff1f;有多个user-service实例地址&#xff0c;…

【探究图论中dfs记忆化,搜索,递推,回溯关系】跳棋,奶牛隔间, 小A和uim之大逃离 II

本篇很高能&#xff0c;如有错误欢迎指出&#xff0c;本人能力有限&#xff08;需要前置知识记忆化dfs&#xff0c;树形dp&#xff0c;bfsdp&#xff0c;tarjan&#xff09; 另外&#xff0c;本篇之所以属于图论&#xff0c;也是想让各位明白&#xff0c;dfs就是就是在跑图&am…

c语言中的柔性数组

目录 1.柔性数组的特点 2.柔性数组的创建和简单使用 3.柔性数组的优势 何为柔性数组&#xff08;Flexible Array&#xff09; 柔性数组在C语言的 C99 标准中&#xff0c;引入的新特性。结构中的最后一个元素的大小允许是未知的数组&#xff0c;即为柔性数组。 struct S {in…

更高效稳定 | 基于ACM32 MCU的编程直流电源应用方案

随着电子设备的多样化发展&#xff0c;面对不同的应用场景&#xff0c;需要采用特定的供电电源。因此&#xff0c;在电子产品的开发测试过程中&#xff0c;必不可少使用编程直流电源来提供测试电压&#xff0c;协助完成初步的开发测试过程。 编程直流电源概述 编程直流电源结构…

[Linux]知识整理(持续更新)

前言 Linux的目录结构 Linux的目录结构是一个树型结构 Windows 系统可以拥有多个盘符, 如 C盘、D盘、E盘 Linux没有盘符这个概念, 只有一个根目录 /, 所有文件都在它下面 Linux路径的描述方式 第一章 基本命令 命令格式 例:ls –la /etc 说明: 1)个别命令使用不遵循…

大语言模型(LLM)token解读

1. 什么是token&#xff1f; 人们经常在谈论大模型时候&#xff0c;经常会谈到模型很大&#xff0c;我们也常常会看到一种说法&#xff1a; 参数会让我们了解神经网络的结构有多复杂&#xff0c;而token的大小会让我们知道有多少数据用于训练参数。 什么是token&#xff1f;比…

gitee拉取与推送

&#x1f331;博客主页&#xff1a;青竹雾色间 &#x1f618;博客制作不易欢迎各位&#x1f44d;点赞⭐收藏➕关注 目录 一&#xff0c;从本地推送项目到gitee1.首先我们在gitee上创建一个仓库2.clone远程仓库到本地3.git的三板斧3.1. add - 将代码添加到本地仓库3.2. commit …