Java桥接模式源码剖析及使用场景
目录
- 一、介绍
- 二、项目管理系统中使用桥接模式
- 三、权限管理中使用桥接模式
- 四、Java JDBC中使用桥接模式
一、介绍
它的主要目的是将抽象化与实现化分离,使得二者可以独立变化,就像一个桥,将两个变化维度连接起来。各个维度都可以独立的变化。故称之为:桥接模式
桥接模式的核心在于通过一个桥接接口,将抽象部分与实现部分解耦。这样做的好处是显而易见的,当系统中的某个维度(抽象或实现)需要变更时,不会影响到另一个维度。具体来说,桥接模式涉及以下几个关键角色:
-
抽象化角色(Abstraction):它是抽象类的接口,定义了一个实现化的引用和对实现化的操作。
-
修正抽象化角色(Refined Abstraction):它是扩展了抽象化角色的子类,在实际应用中,具体的业务逻辑通常在这个角色中实现。
-
实现化角色(Implementor):这个角色定义了一个接口,由具体实现化角色来实现。
-
具体实现化角色(Concrete Implementor):这个角色实现了实现化接口的具体类。
二、项目管理系统中使用桥接模式
需求:项目管理系统,包含多种任务(编码任务,测试任务)和多种任务执行(本地执行,远程执行)方式 。还有开发和测试角色。我们可以使用桥接模式来分离任务和任务执行方式的实现,以便它们可以独立变化。
- 定义项目管理系统中的任务接口
public interface Task {void performTask();
}
- 具体的任务实现类
// 编码任务
public class CodingTask implements Task {@Overridepublic void performTask() {System.out.println("Performing coding task");}
}// 测试任务
public class TestingTask implements Task {@Overridepublic void performTask() {System.out.println("Performing testing task");}
}
- 任务执行方式接口
public interface TaskExecution {void executeTask();
}
- 具体的任务执行方式实现类
// 本地执行任务
public class LocalTaskExecution implements TaskExecution {@Overridepublic void executeTask() {System.out.println("Executing task locally");}
}// 远程执行任务
public class RemoteTaskExecution implements TaskExecution {@Overridepublic void executeTask() {System.out.println("Executing task remotely");}
- 项目管理系统角色抽象类
public abstract class ProjectRole {protected Task task;protected TaskExecution taskExecution;public void setTask(Task task) {this.task = task;}public void setTaskExecution(TaskExecution taskExecution) {this.taskExecution = taskExecution;}public abstract void performProjectTask();
}
- 项目管理系统具体角色实现类
// 开发人员角色
public class Developer extends ProjectRole {@Overridepublic void performProjectTask() {System.out.print("Developer role: ");task.performTask();System.out.print("Using ");taskExecution.executeTask();}
}// 测试人员角色
public class Tester extends ProjectRole {@Overridepublic void performProjectTask() {System.out.print("Tester role: ");task.performTask();System.out.print("Using ");taskExecution.executeTask();}
}
- 客户端代码演示桥接模式的使用
public class BridgePatternDemo {public static void main(String[] args) {Task codingTask = new CodingTask();Task testingTask = new TestingTask();TaskExecution localTaskExecution = new LocalTaskExecution();TaskExecution remoteTaskExecution = new RemoteTaskExecution();// 创建不同角色的实例ProjectRole developer = new Developer();ProjectRole tester = new Tester();// 设置不同的任务和任务执行方式developer.setTask(codingTask);developer.setTaskExecution(remoteTaskExecution);tester.setTask(testingTask);tester.setTaskExecution(localTaskExecution);// 视图数据developer.performProjectTask(); // Output: "Developer role: Performing coding task Using Executing task remotely"tester.performProjectTask(); // Output: "Tester role: Performing testing task Using Executing task locally"}
}
大家说上面七步是桥接模式吗?在实际项目中,我们可以根据需要添加更多的任务和任务执行方式,而不需要修改已有的代码。核心在于正确识别并分离出两个独立的维度,并且这两个维度应该能够各自独立地变化和扩展。
三、权限管理中使用桥接模式
需求:权限管理系统,分别有普通角色、管理员角色、超级管理员角色。以数据权限设计,普通角色只能看到自己操作的数据,管理员角色可以看到普通角色操作的数据,超级管理员角色可以看到所有角色的数据。
- 定义数据权限控制策略接口
public interface DataPermissionControlStrategy {void process();
}
- 定义具体的数据权限控制策略实现类
// 普通角色只能看到自己操作的数据
public class NormalDataPermissionControlStrategy implements DataPermissionControlStrategy {@Overridepublic void process() {System.out.println("Normal role can only access own data");}
}// 管理员角色可以看到普通角色操作的数据
public class AdminDataPermissionControlStrategy implements DataPermissionControlStrategy {@Overridepublic void process() {System.out.println("Admin role can access normal role's data");}
}// 超级管理员角色可以看到所有角色的数据
public class SuperAdminDataPermissionControlStrategy implements DataPermissionControlStrategy {@Overridepublic void process() {System.out.println("Super admin role can access all data");}
}
- 定义用户角色抽象类
public abstract class UserRole {protected DataPermissionControlStrategy dataPermissionControlStrategy;public void setDataPermissionControlStrategy(DataPermissionControlStrategy dataPermissionControlStrategy) {this.dataPermissionControlStrategy = dataPermissionControlStrategy;}public abstract void viewData();
}
- 定义具体的用户角色实现类
// 普通角色
public class NormalRole extends UserRole {@Overridepublic void viewData() {System.out.print("Normal role: ");dataPermissionControlStrategy.process();}
}// 管理员角色
public class AdminRole extends UserRole {@Overridepublic void viewData() {System.out.print("Admin role: ");dataPermissionControlStrategy.process();}
}// 超级管理员角色
public class SuperAdminRole extends UserRole {@Overridepublic void viewData() {System.out.print("Super admin role: ");dataPermissionControlStrategy.process();}
}
- 客户端代码演示桥接模式的使用
// 客户端代码演示桥接模式的使用
public class BridgePatternDemo {public static void main(String[] args) {DataPermissionControlStrategy normalStrategy = new NormalDataPermissionControlStrategy();DataPermissionControlStrategy adminStrategy = new AdminDataPermissionControlStrategy();DataPermissionControlStrategy superAdminStrategy = new SuperAdminDataPermissionControlStrategy();// 创建不同角色的实例UserRole normalUser = new NormalRole();UserRole adminUser = new AdminRole();UserRole superAdminUser = new SuperAdminRole();// 设置不同的数据权限控制策略normalUser.setDataPermissionControlStrategy(normalStrategy);adminUser.setDataPermissionControlStrategy(adminStrategy);superAdminUser.setDataPermissionControlStrategy(superAdminStrategy);// 视图数据normalUser.viewData(); // Output: "Normal role: Normal role can only access own data"adminUser.viewData(); // Output: "Admin role: Admin role can access normal role's data"superAdminUser.viewData(); // Output: "Super admin role: Super admin role can access all data"}
}
四、Java JDBC中使用桥接模式
在Java JDBC中,桥接模式并不是直接使用的设计模式。然而,在JDBC中,可以看到一些类似于桥接模式的结构和思想。
1.DataSource 接口:在JDBC中,DataSource 是一个接口,它提供了获取数据库连接的方法。不同的数据库厂商(比如MySQL、Oracle等)都会有对应的DataSource 实现类。这种设计类似于桥接模式中的抽象部分。
2.Connection 接口和实现类:Connection 接口代表着一个数据库连接,而具体的数据库连接操作是由各个数据库厂商提供的实现类来完成的,比如MySQLConnection、OracleConnection 等。这也体现了桥接模式中的实现部分。
通过接口和实现类的结合,实现了对不同数据库的访问和操作,并且很好地解耦了抽象和实现部分。
// 1.定义厂商DataSource 接口
public interface DataSource {Connection getConnection();
}// 2.MySQLDataSource 实现类
public class MySQLDataSource implements DataSource {@Overridepublic Connection getConnection() {// 返回 MySQL 数据库连接return new MySQLConnection();}
}// 3.OracleDataSource 实现类
public class OracleDataSource implements DataSource {@Overridepublic Connection getConnection() {// 返回 Oracle 数据库连接return new OracleConnection();}
}// 4.不同的数据库不同的连接方法Connection 接口
public interface Connection {void executeQuery(String query);
}// 5.MySQLConnection 实现类
public class MySQLConnection implements Connection {@Overridepublic void executeQuery(String query) {// 在 MySQL 数据库中执行查询System.out.println("Executing query in MySQL database: " + query);}
}// 6.OracleConnection 实现类
public class OracleConnection implements Connection {@Overridepublic void executeQuery(String query) {// 在 Oracle 数据库中执行查询System.out.println("Executing query in Oracle database: " + query);}
}相关文章:
Java桥接模式源码剖析及使用场景
目录 一、介绍二、项目管理系统中使用桥接模式三、权限管理中使用桥接模式四、Java JDBC中使用桥接模式 一、介绍 它的主要目的是将抽象化与实现化分离,使得二者可以独立变化,就像一个桥,将两个变化维度连接起来。各个维度都可以独立的变化。…...
【异常处理】verilator安装时出现异常 make: *** [Makefile:195: verilator_gantt.1] Error 13
在ubuntu中安装verilator工具时执行make出现该报错。 当我出现这个报错的时候我一脸懵逼,因为网上找不到相关解决办法。 后来想到我的verilator是从github上下载zip,然后解压后传到ubuntu上的,windows上解压我记得会把-替换成_,这…...
测试一下 Anthropic 宣称超过 GPT-4 的 Claude 3 Opus
测试一下 Anthropic 宣称超过 GPT-4 的 Claude 3 Opus 0. 引言1. 测试 Claude 3 Opus3. 试用 api key 限制 0. 引言 今天测试一下 Anthropic 发布的 Claude 3 Opus。 3月4日,Anthropic 宣布推出 Claude 3 型号系列,该系列在广泛的认知任务中树立了新的…...
【题解】—— LeetCode一周小结10
【题解】—— 每日一道题目栏 上接:【题解】—— LeetCode一周小结9 4.用栈实现队列 题目链接:232. 用栈实现队列 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):…...
Android studio虚拟调试出现“我的APP keeps stopping”问题
问题如图: 遇到这种情况,一看代码,也没有报错呀,怎么不能运行呢?不要慌!我们一步一步来。 1、查看Logcat日志 在Android Studio中查看Logcat窗口,可以获取应用程序崩溃时的详细错误信息&…...
【Web】浅聊Java反序列化之Spring2链——两层动态代理
目录 简介 简话JdkDynamicAopProxy 关于target的出身——AdvisedSupport EXP 请确保已阅读过前文或对Spring1链至少有一定认知:【Web】浅聊Java反序列化之Spring1链——三层动态代理-CSDN博客 简介 Spring2 和 Spring1 的反序列化过程基本相同,唯一…...
2386. 找出数组的第 K 大和
2386. 找出数组的第 K 大和 题目链接:2386. 找出数组的第 K 大和 代码如下: //优先队列 //参考:https://leetcode.cn/problems/find-the-k-sum-of-an-array/solutions/2668280/zhao-chu-shu-zu-de-di-k-da-he-by-leetcod-z5kq class Soluti…...
Pytorch学习 day10(L1Loss、MSELoss、交叉熵Loss)
Loss loss的作用如下: 计算实际输出和真实值之间的差距为我们更新模型提供一定的依据(反向传播) L1Loss 绝对值损失函数:在每一个batch_size内,求每个输入x和标签y的差的绝对值,最后返回他们平均值 M…...
2.2 传统经济学在耍赖
传统经济学中,主体的行为决策是研究的重点对幸福的追求不是传统经济学的研究重点,决策才是。在传统经济学那里,只要能搞清楚是什么决定了决策就可以了。 传统经济学用人们对物品的喜好的排序去替代了对幸福的直接度量。这样做有一个好处&…...
【算法面试题】-04
执行时长 def min_execution_time(n, size, tasks):a 0ans sizei 0while i < size:tmp tasks[i]a tmpif a < n:a 0else:a - ni 1ans a // nif a % n ! 0:ans 1return ans# 读取输入 n int(input()) size int(input()) tasks list(map(int, input().split()))…...
力扣hot100:152.乘积最大子数组(动态规划)
一个子数组问题,我们要使用线性dp,最好先考虑以i结尾,如果定义dp[i]为前i个数最大子数组乘积值 那么dp[i-1]就无法转移到dp[i]。因此我们先考虑dp[i]定义为以第i个数结尾的最大子数组乘积值。 53. 最大子数组和 最大子数组和是一个动态规划问…...
【python 】----Pytest基础知识与进阶知识
定义 用于编写和执行Python测试全功能测试框架(工具),是一个第三方库 安装 pip insatll pytest 安装pytest --version 校验 pytest的组成构成 不写调用语句也可以执行函数内容 在用例运行语句里面: -s:指的是开启与终端的交互,如果没有-s(程序不会输入与打印),一条用…...
谷歌开源的LLM大模型 Gemma 简介
相关链接: Hugging face模型下载地址:https://huggingface.co/google/gemma-7bGithub地址:https://github.com/google/gemma_pytorch论文地址:https://storage.googleapis.com/deepmind-media/gemma/gemma-report.pdf官方博客&…...
深入理解 Vuex:从基础到应用场景
前言 在之前的文章中,我们已经对 Vue.js 有了一定的了解。今天我们要对Vue官方的状态共享管理器Vuex进行详细讲解,将其基本吃透,目标是面对大多数业务需求; 一、介绍 Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用…...
自定义 classNames hooks
什么是自定义 hooks 自定义hooks是react提供的编写公共函数的方法 自定hooks 和 通用函数的区别 一定有人会说 hooks 可以使用react 的方法,但是公共函数也可以,因为 jsx 语法的原因 函数必须开头进行大写 其实这些都是 react 的语法规范ÿ…...
玩转centos 下的core 文件
玩转centos 下的core 文件 ------------------------------------------------------------ author: hjjdebug date: 2024年 03月 06日 星期三 12:38:35 CST description: 玩转centos 下的core 文件 ------------------------------------------------------------ 一: 准备一…...
深入浅出计算机网络 day.1 概论③ 电路交换、分组交换和报文交换
人无法同时拥有青春和对青春的感受 —— 04.3.9 内容概述 01.电路交换、分组交换和报文交换 02.三种交换方式的对比 一、电路交换、分组交换和报文交换 1.电路交换 计算机之间的数据传送是突发式的,当使用电路交换来传送计算机数据时,其线路的传输效率一…...
linux:线程的控制
个人主页 : 个人主页 个人专栏 : 《数据结构》 《C语言》《C》《Linux》 文章目录 前言一、线程的总结1. 线程的优点2. 线程的缺点3. 线程异常4.线程和进程 二、线程的控制创建线程线程终止线程等待获取返回值 线程分离 总结 前言 本文作为我对于线程的…...
小程序分账方案:实现商户分账的简便与灵活
随着移动支付的普及和小程序的快速发展,越来越多的商家选择在微信小程序上开展业务。然而,对于一些有多个分账方的商户而言,如何实现快速、准确和灵活的资金分账成为了一个挑战。本文将介绍一种高效的小程序分账方案,帮助商户轻松…...
Python数值微积分,摆脱被高数支配的恐惧
文章目录 差分和累加积分多重积分 Python科学计算:数组💯数据生成 差分和累加 微积分是现代科学最基础的数学工具,但其应用对象往往是连续函数,而其在非连续函数的类比,便是差分与累加。在【numpy】中,可…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...
面向无人机海岸带生态系统监测的语义分割基准数据集
描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...
C/C++ 中附加包含目录、附加库目录与附加依赖项详解
在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...
