重读Java设计模式: 桥接模式详解

引言

在软件开发中,经常会遇到需要在抽象与实现之间建立连接的情况。当系统需要支持多个维度的变化时,使用传统的继承方式往往会导致类爆炸和耦合度增加的问题。为了解决这一问题,我们可以使用桥接模式。桥接模式是一种结构型设计模式,它将抽象部分与其实现部分分离,使它们可以独立地变化。本文将深入探讨桥接模式的概念、应用场景以及在实际项目中的实现方式。

一、理解桥接模式

1.1 什么是桥接模式?

桥接模式是一种结构型设计模式,旨在将抽象部分与其实现部分分离,使它们可以独立地变化。桥接模式通过将抽象和实现解耦,使得它们可以独立地扩展,而不会相互影响。这种分离使得系统更加灵活,可以应对不断变化的需求。

1.2 桥接模式的角色

在桥接模式中,通常有以下几个角色:

  • 抽象化(Abstraction):定义抽象类的接口,并维护一个指向实现化对象的引用。
  • 扩展抽象化(Refined Abstraction):对抽象化角色进行扩展,实现更加精细的抽象接口。
  • 实现化(Implementor):定义实现类的接口,供抽象化角色调用。
  • 具体实现化(Concrete Implementor):具体的实现类,实现了实现化角色定义的接口。

二、桥接模式的应用场景

2.1 多维度变化的情况

当一个类存在多个变化维度,并且这些变化维度需要独立扩展时,可以考虑使用桥接模式。例如,一个形状类有不同的颜色和绘制方式,可以使用桥接模式将形状与颜色、绘制方式分离,实现各自独立的扩展。

2.2 需要避免使用继承的情况

在传统的继承方式中,类的继承关系是静态的,一旦继承关系确定,就不容易变化。而使用桥接模式可以在运行时动态地选择抽象和实现的组合,避免了继承方式的静态性。

三、Java 中的桥接模式实现

在 Java 中,桥接模式的实现通常通过接口和实现类组合的方式来实现。我们就以上面说的一个形状有不同的颜色和绘制方式,可以使用桥接模式将形状与颜色方式分离,实现各自独立的扩展举例

先来看下示例的 UML 图:

  • 抽象化与扩展抽象化部分
public abstract class Shape {protected final DrawApi drawApi;public Shape(DrawApi api) {this.drawApi = api;}public abstract void draw();
}public class Circle extends Shape {public Circle(DrawApi api) {super(api);}@Overridepublic void draw() {System.out.println("Draw Circle : " + drawApi.draw());}
}public class Square extends Shape {public Square(DrawApi api) {super(api);}@Overridepublic void draw() {System.out.println("Draw Square: " + drawApi.draw());}
}
  • 实现化部分与具体实现化部分
public interface DrawApi {String draw();
}public class RedDraw implements DrawApi{@Overridepublic String draw() {return "使用红色颜料画图";}
}public class BlueDraw implements DrawApi{@Overridepublic String draw() {return "使用蓝色颜料画图";}
}
  • 客户端部分
package com.markus.desgin.mode.structural.bridge;/*** @Author: zhangchenglong06* @Date: 2024/3/12* @Description:*/
public class BridgePatternDemo {/*** Spring 中 JdbcTemplate 和 DataSource 之间的关系就是一种 桥接模式* @param args*/public static void main(String[] args) {RedDraw redDraw = new RedDraw();BlueDraw blueDraw = new BlueDraw();Shape red = new Circle(redDraw);Shape blue = new Circle(blueDraw);red.draw();blue.draw();red = new Square(redDraw);blue = new Square(blueDraw);red.draw();blue.draw();}
}

四、桥接模式在 Spring 框架中的应用

在 Spring 框架中,使用桥接模式的一个典型例子是在 JdbcTemplateDataSource 之间。这两个组件是 Spring 框架中处理数据库操作的核心组件之一。

JdbcTemplate

JdbcTemplate 是 Spring 框架提供的一个用于简化 JDBC 编程的类,它封装了大量的 JDBC 操作,使得开发者可以通过简单的方法调用来执行数据库查询、更新等操作,而无需手动管理数据库连接、预处理语句、结果集等资源。通过使用 JdbcTemplate,开发者可以专注于业务逻辑的实现,而不用过多关注底层的数据库操作细节。

DataSource

DataSource 是 Java 中用于管理数据库连接的接口,它定义了一系列获取数据库连接的方法,如 getConnection()getConnection(username, password) 等。在实际应用中,DataSource 通常是由数据库厂商提供的具体实现,比如 Apache 的 Commons DBCP、C3P0 等。

桥接模式应用

Spring 框架中使用桥接模式的地方就是在 JdbcTemplateDataSource 之间的连接。具体来说,JdbcTemplate 充当了抽象化角色,而 DataSource 则充当了实现化角色。通过在 JdbcTemplate 中注入 DataSource 实例,Spring 可以利用桥接模式将两者连接起来,实现数据库操作的统一接口。这样一来,JdbcTemplate 就可以使用 DataSource 提供的数据库连接,从而执行相应的 SQL 操作。

下面是一个简单的示例代码,演示了 JdbcTemplateDataSource 之间的桥接模式应用:

@Configuration
public class AppConfig {@Beanpublic DataSource dataSource() {// 配置数据源,这里使用 HikariCP 数据源作为示例HikariConfig config = new HikariConfig();config.setJdbcUrl("jdbc:mysql://localhost:3306/mydatabase");config.setUsername("username");config.setPassword("password");return new HikariDataSource(config);}@Beanpublic JdbcTemplate jdbcTemplate(DataSource dataSource) {// 注入数据源到 JdbcTemplate 中return new JdbcTemplate(dataSource);}
}

在上面的示例中,我们通过 @Bean 注解配置了一个 DataSource 实例,并将其注入到 JdbcTemplate 中。这样一来,在其他组件中就可以直接注入 JdbcTemplate,然后使用它来执行数据库操作,而不用关心底层的数据库连接细节。

总之,Spring 框架中使用桥接模式将 JdbcTemplateDataSource 结合起来,使得开发者可以更加便捷地进行数据库操作,提高了开发效率和代码的可维护性。

五、设计模式百宝箱

  • 在本节,我们继续填充我们的百宝箱:

    • 面向对象基础
      • 抽象
      • 封装
      • 多态
      • 继承
    • 面向对象原则
      • 依赖抽象,不要依赖具体类
      • 针对接口编程,不针对具体实现编程
      • 类应该对扩展开放,对修改关闭
      • 为交互对象之间的松耦合设计而努力
      • 多用组合,少用继承
    • 面向对象设计模式
      • 简单工厂模式:定义了一个创建对象的接口,将创建对象的内容从客户端抽离出来
      • 抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类
      • 原型模式:通过复制现有对象来创建新对象,提高代码效率和可维护性
      • 建造者模式:将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示
      • 适配器模式:将一个类的接口转换成客户期望的另一个接口。适配器让原来接口不兼容的类可以合作无间
      • 桥接模式:将抽象与实现分离,不止改变你的实现,也能改变你的抽象

六、总结

总结一下,本篇文章详细介绍了桥接模式在 Java 设计中的应用,以及在 Spring 框架中的实际应用。首先,它解释了桥接模式的基本概念和角色,以及适用场景。然后,通过一个形状与颜色绘制方式分离的示例展示了桥接模式的实现。最后,以 JdbcTemplate 和 DataSource 之间的关系为例,说明了桥接模式在 Spring 中的应用,通过桥接模式将两者连接起来,实现了数据库操作的统一接口。

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

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

相关文章

ARM架构学习笔记2-汇编

RISC是精简指令集计算机(RISC:Reduced Instruction Set Computing) ARM汇编概述 一开始,ARM公司发布两类指令集: ① ARM指令集,这是32位的,每条指令占据32位,高效,但是太占空间 2…

物联网实战--入门篇之(十)安卓QT--后端开发

目录 一、项目配置 二、MQTT连接 三、数据解析 四、数据更新 五、数据发送 六、指令下发 一、项目配置 按常规新建一个Quick空项目后,我们需要对项目内容稍微改造、规划下。 首先根据我们的需要在.pro文件内添加必要的模块,其中quick就是qml了&…

燃气管网安全运行监测系统功能介绍

燃气管网,作为城市基础设施的重要组成部分,其安全运行直接关系到居民的生命财产安全和城市的稳定发展。然而,随着城市规模的不断扩大和燃气使用量的增加,燃气管网的安全运行面临着越来越大的挑战。为了应对这些挑战,燃…

虚幻UE5智慧城市全流程开发教学

一、背景 这几年,智慧城市/智慧交通/智慧水利等飞速发展,骑士特意为大家做了一个这块的学习路线。 二、这是学习大纲 1.给虚幻UE5初学者准备的智慧城市/数字孪生蓝图开发教程 https://www.bilibili.com/video/BV1894y1u78G 2.UE5数字孪生蓝图开发教学…

蓝桥集训之斐波那契数列

蓝桥集训之斐波那契数列 核心思想&#xff1a;矩阵乘法 将原本O(n)的递推算法优化为O(log2n) 构造1x2矩阵f和2x2矩阵a 发现f(n1) f(n) * a 则f(n1) f(1) * an可以用快速幂优化 #include <iostream>#include <cstring>#include <algorithm>using na…

算法刷题应用知识补充--基础算法、数据结构篇

这里写目录标题 位运算&#xff08;均是拷贝运算&#xff0c;不会影响原数据&#xff0c;这点要注意&#xff09;&、|、^位运算特性细节知识补充对于n-1的理解异或来实现数字交换找到只出现一次的数据&#xff0c;其余数据出现偶数次 >> 、<<二进制中相邻的位的…

第12届蓝桥杯省赛 ---- C/C++ C组

文章目录 1. ASC2. 空间3. 卡片4. 相乘5. 路径6.时间显示7.最少砝码8. 杨辉三角形9. 左孩子右兄弟 第12届蓝桥杯省赛&#xff0c;C/C C组真题&#xff0c;第10题不是很清楚&#xff0c;题解不敢乱放&#x1f601;&#x1f601;&#x1f601; 1. ASC 额。。。。 #include <i…

【WEEK6】 【DAY1】DQL查询数据-第一部分【中文版】

2024.4.1 Monday 目录 4.DQL查询数据&#xff08;重点&#xff01;&#xff09;4.1.Data Query Language查询数据语言4.2.SELECT4.2.1.语法4.2.2.实践4.2.2.1.查询字段 SELECT 字段/* FROM 表查询全部的某某查询指定字段 4.2.2.2.给查询结果或者查询的这个表起别名&#xff08…

Spark-Scala语言实战(13)

在之前的文章中&#xff0c;我们学习了如何在spark中使用键值对中的keys和values,reduceByKey,groupByKey三种方法。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢…

【瑞萨RA6M3】1. 基于 vscode 搭建开发环境

基于 vscode 搭建开发环境 1. 准备2. 安装2.1. 安装瑞萨软件包2.2. 安装编译器2.3. 安装 cmake2.4. 安装 openocd2.5. 安装 ninja2.6. 安装 make 3. 生成初始代码4. 修改 cmake 脚本5. 调试准备6. 仿真 1. 准备 需要瑞萨仓库中的两个软件&#xff1a; MDK_Device_Packs.zipse…

浅谈物联网高速公路智慧配电室系统构建方案

关键词&#xff1a;高速公路&#xff1b;智慧供配电&#xff1b;电力监控&#xff1b;配电室智能运维托管&#xff1b;安全隐患 0、引言 随着高速公路事业的不断发展和路网的不断延伸&#xff0c;传统的管理方式已难以满足日益增长的需求&#xff0c;动态管理和安全隐患预警成…

ubuntu16如何使用高版本cmake

1.引言 最近在尝试ubuntu16.04下编译开源项目vsome&#xff0c;发现使用apt命令默认安装cmake的的版本太低。如下 最终得知&#xff0c;ubuntu16默认安装确实只能到3.5.1。解决办法只能是源码安装更高版本。 2.源码下载3.20 //定位到opt目录 cd /opt 下载 wget https://cmak…

ADB 命令之 模拟按键/输入

ADB 命令之 模拟按键/输入 模拟按键/输入 在 ​​adb shell​​​ 里有个很实用的命令叫 ​​input​​&#xff0c;通过它可以做一些有趣的事情。 ​​input​​ 命令的完整 help 信息如下&#xff1a; Usage: input [<source>] <command> [<arg>...] Th…

leetcode.面试题 02.07. 链表相交

题目 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 思路 假a在链表A上移动,b在链表B上移动&#xff0c;a移动完在B上开始&…

javaweb学习(day11-监听器Listener过滤器Filter)

一、监听器Listener 1 Listener介绍 Listener 监听器它是 JavaWeb 的三大组件之一。JavaWeb 的三大组件分别是&#xff1a;Servlet 程 序、Listener 监听器、Filter 过滤器 Listener 是 JavaEE 的规范&#xff0c;就是接口 监听器的作用是&#xff0c;监听某种变化(一般就是对…

XRDP登录ubuntu桌面闪退问题

修改 /etc/xrdp/startwm.sh unset DBUS_SESSION_BUS_ADDRESS unset XDG_RUNTIME_DIR . $HOME/.profile

​如何使用ArcGIS Pro进行洪水淹没分析

洪水淹没分析是一种常见的水文地理信息系统应用&#xff0c;用于模拟和预测洪水事件中可能受到淹没影响的地区&#xff0c;这里为大家介绍一下ArcGIS Pro进行洪水淹没分析的方法&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载的DEM数据&…

数据结构(六)——图的应用

6.4 图的应用 6.4.1 最小生成树 对于⼀个带权连通⽆向图G (V, E)&#xff0c;⽣成树不同&#xff0c;每棵树的权&#xff08;即树中所有边上的权值之和&#xff09;也可能不同。设R为G的所有⽣成树的集合&#xff0c;若T为R中边的权值之和最小的生成树&#xff0c;则T称为G的…

怎样把学浪上的视频保存到电脑

怎样把学浪上的视频保存到电脑,这里给大家一个工具,专门用来下载学浪上的视频 这个工具叫做小浪助手.exe 我已经打包好了,有需要的自己取一下 链接&#xff1a;https://pan.baidu.com/s/1y7vcqILToULrYApxfEzj_Q?pwdkqvj 提取码&#xff1a;kqvj --来自百度网盘超级会员V…

【三维重建】3D Gaussian Splatting:实时的神经场渲染

文章目录 摘要一、前言二、相关工作1.传统的场景重建与渲染2.神经渲染和辐射场3.基于点的渲染和辐射场4.*什么是 Tile-based rasterizer (快速光栅化) 三、OVERVIEW四、可微的三维高斯 Splatting五、三维高斯 自适应密度控制的优化1.优化2.高斯的自适应控制 六、高斯分布的快速…