news 2026/4/28 18:20:00

设计模式学习(9) 23-7 桥接模式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
设计模式学习(9) 23-7 桥接模式

文章目录

  • 0.个人感悟
  • 1. 概念
  • 2. 适配场景(什么场景下使用)
    • 2.1 适合的场景
    • 2.2 常见场景举例
  • 3. 实现方法
    • 3.1 实现思路
    • 3.2 UML类图
    • 3.3 代码示例
  • 4. 优缺点
    • 4.1优点分析
    • 4.2缺点分析
  • 5. 源码分析:JDBC中的桥接模式
    • 5.1 源码分析
    • 5.2 JDBC桥接模式的优势

0.个人感悟

  1. 桥接模式,桥接,作为一个桥梁连接系统的抽象化部分和实现化部分,让它们解耦。解耦的好处多多,包括可以独立演变等
  2. 关键(痛点)是怎么理解和识别抽象部分和实现化部分。结合自己的经验提供参考:
    • 抽象化部分: 核心职责是定义要做什么,业务流程、高层逻辑框架和策略,对具体化部分是依赖关系
    • 实现化部分: 核心职责是定义具体怎么做,提供共底层、平台相关的具体实现,通常是系统中已有的组件
  3. 实际工作中很少用到桥接模式。但是学习这个模式,有利于感受软件设计中开闭(对修改关闭 对扩展开放)的魅力
  4. 对于JDBC中桥接模式的理解,网上有不同的观点。其实我觉得没必要争论谁对谁错,不妨自己去看看源码,有自己的判断,软件设计没有绝对的正确和错误

1. 概念

英文定义(《设计模式:可复用面向对象软件的基础》):

Decouple an abstraction from its implementation so that the two can vary independently.

中文翻译:

将抽象部分与它的实现部分分离,使它们都可以独立地变化。

理解:

  • 核心思想: 使用组合代替继承,将抽象层次与实现层次分离
  • 关键要点:
    • 分离关注点: 将复杂的系统分解为两个独立的维度:抽象(高层逻辑)和实现(底层细节)
    • 独立演化: 抽象层次和实现层次可以各自独立地扩展,互不影响
    • 避免类爆炸: 当系统有多个变化维度时,避免创建大量子类
    • 运行时绑定: 抽象和实现之间的组合关系可以在运行时动态建立

2. 适配场景(什么场景下使用)

2.1 适合的场景

  1. 多个维度变化: 当系统有两个或多个独立变化的维度,且这些维度都可能扩展时
  2. 避免继承层次过深: 当使用继承会导致类层次结构过于复杂,产生"类爆炸"问题时
  3. 运行时切换实现: 需要在运行时动态切换不同的实现时

2.2 常见场景举例

  1. GUI框架: 窗口(抽象)与窗口实现(具体平台:Windows、Linux、Mac)
  2. 数据库驱动: JDBC。这个有很多解读,后面会提供一种我比较认可的理解
  3. 日志系统: 日志接口(抽象)与日志输出方式(文件、控制台、网络)
  4. 支付系统: 支付接口(抽象)与具体支付方式(支付宝、微信、银行卡)
  5. 绘图工具: 形状(抽象)与渲染引擎(矢量、栅格)

3. 实现方法

3.1 实现思路

  1. 识别两个独立变化维度: 分析系统,找出两个可以独立变化的维度
  2. 定义实现化接口(Implementor): 创建实现部分的接口,定义基本操作
  3. 创建具体实现化类(ConcreteImplementor): 实现Implementor接口,提供具体的底层实现
  4. 定义抽象化类(Abstraction):
    • 创建抽象部分基类
    • 持有对Implementor的引用(组合关系)
    • 定义基于Implementor的高层操作
  5. 创建扩展抽象化类(RefinedAbstraction): 继承Abstraction,扩展或修改其行为
  6. 客户端使用: 客户端创建具体实现化对象,将其传递给抽象化对象使用

3.2 UML类图

角色说明:

  • Abstraction (抽象化角色): 定义抽象接口,维护对Implementor的引用
  • RefinedAbstraction (扩展抽象化角色): 扩展抽象接口,通常比Abstraction更具体
  • Implementor (实现化角色): 定义实现类的接口,提供基本操作
  • ConcreteImplementor (具体实现化角色): 实现Implementor接口,提供具体实现

3.3 代码示例

背景:以遥控器和TV为例:
传统方式设计,层次是
遥控器接口->遥控器实现(初级遥控器 高级遥控器)-> 厂商遥控器(遥控器类型x厂商组合)
这样进行扩展的话,会有M种电视 x N种遥控器的组合,导致类爆炸,也不利于复用
使用桥接模式可以解决上面的问题
实现化部分的接口和实现:

publicinterfaceTV{/** * @description 开机 * @author bigHao * @date 2026/1/6 **/voidon();/** * @description 关机 * @author bigHao * @date 2026/1/6 **/voidoff();/** * @param channel 频道 * @description 换台 * @author bigHao * @date 2026/1/6 **/voidtuneChannel(intchannel);}publicclassSonyTVimplementsTV{@Overridepublicvoidon(){System.out.println("索尼电视:开启,展示LOGO");}@Overridepublicvoidoff(){System.out.println("索尼电视:进入待机模式");}@OverridepublicvoidtuneChannel(intchannel){System.out.println("索尼电视:切换到频道"+channel);}}publicclassSamsungTVimplementsTV{@Overridepublicvoidon(){System.out.println("三星电视:快速启动");}@Overridepublicvoidoff(){System.out.println("三星电视:完全关闭");}@OverridepublicvoidtuneChannel(intchannel){System.out.println("三星电视:智能跳转到频道"+channel);}}

抽象化角色和扩展抽象化角色

abstractclassRemoteControl{protectedTVtv;publicRemoteControl(TVtv){this.tv=tv;}/** * @description 开机 * @author bigHao * @date 2026/1/6 **/publicabstractvoidturnOn();/** * @description 关机 * @author bigHao * @date 2026/1/6 **/publicabstractvoidturnOff();}publicclassAdvanceRemoteControlextendsRemoteControl{publicAdvanceRemoteControl(TVtv){super(tv);}@OverridepublicvoidturnOn(){tv.on();}@OverridepublicvoidturnOff(){tv.off();}// 扩展功能/** * @param channel 频道 * @description 换台 * @author bigHao * @date 2026/1/6 **/publicvoidsetChannel(intchannel){System.out.print("高级遥控器指令:");tv.tuneChannel(channel);// 依然调用具体实现}}

客户端;

publicclassClient{staticvoidmain(){// 组合1:高级遥控器控制索尼电视TVsony=newSonyTV();RemoteControlremote1=newAdvanceRemoteControl(sony);remote1.turnOn();((AdvanceRemoteControl)remote1).setChannel(5);// 组合2:高级遥控器控制三星电视(抽象与实现可独立替换)TVsamsung=newSamsungTV();RemoteControlremote2=newAdvanceRemoteControl(samsung);remote2.turnOn();((AdvanceRemoteControl)remote2).setChannel(10);}}

输出;

索尼电视:开启,展示LOGO 高级遥控器指令:索尼电视:切换到频道5 三星电视:快速启动 高级遥控器指令:三星电视:智能跳转到频道10

4. 优缺点

4.1优点分析

  1. 高内聚低耦合: 抽象部分与实现部分完全分离,可以独立变化
  2. 复用性:抽象部分和实现部分可以分别复用,组合使用
  3. 可读性:系统分为清晰的抽象层和实现层,易于理解
  4. 维护性:改抽象或实现不影响另一方,符合开闭原则
  5. 稳定性:抽象层提供稳定接口,实现层变化不影响客户端
  6. 单一职责:抽象类负责高层逻辑,实现类负责底层操作
  7. 开闭原则:可以独立扩展抽象层次和实现层次
  8. 合成复用原则:使用组合代替多层继承,减少子类数量

4.2缺点分析

  1. 可读性:对初学者来说,桥接模式的理解和使用有一定难度
  2. 设计难度:需要识别两个维度,设计难度增加

5. 源码分析:JDBC中的桥接模式

5.1 源码分析

对于JDBC中的桥接模式,网上有很多不同的理解,可以见我参考资料列表中文章
跟踪代码分析后,我比较认可这个观点:

JDBC 的桥接模式是一中简化的桥接模式:桥接模式的主要应用场景是某个类存在两个独立变化的维度,且这两个维度都需要进行扩展,而现在仅有 Driver 一个变化维度,DriverManager 没有抽象化父类,它本身也没有任何子类,因此我认为,在 JDBC 中,是一种简化的桥接模式。

代码:

Class.forName("com.mysql.cj.jdbc.Driver");Connectionconn=DriverManager.getConnection("jdbc:mysql://<host>:<port>/<database>");

跟踪代码后可以简化得到类图如下:

5.2 JDBC桥接模式的优势

  1. 真正的平台无关性:应用程序与具体数据库解耦
  2. 标准化接口:统一了各种数据库的访问方式
  3. 生态繁荣:数据集支持只需要实现Driver接口,允许数据库厂商自由竞争和创新
  4. 降低学习成本:开发者只需学习一套API
  5. 长期兼容性:JDBC标准稳定,驱动可以不断优化。这也是面向接口编程的好处

参考:

  • 韩顺平 Java设计模式
  • 张维鹏 Java设计模式之结构型:桥接模式
  • java_my_life 《JAVA与模式》之桥梁模式
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/28 18:17:18

如何快速掌握GraphQL请求:从入门到实战的完整指南

如何快速掌握GraphQL请求&#xff1a;从入门到实战的完整指南 【免费下载链接】graphql-request 项目地址: https://gitcode.com/gh_mirrors/gra/graphql-request GraphQL作为一种现代化的API查询语言&#xff0c;正在逐步改变前后端数据交互的方式。graphql-request作…

作者头像 李华
网站建设 2026/4/25 18:24:37

在线服务SLA保障:ms-swift部署后的延迟与可用性监控

在线服务SLA保障&#xff1a;ms-swift部署后的延迟与可用性监控 在大模型逐步渗透至搜索、推荐、客服等核心业务的今天&#xff0c;一个看似简单的问题却频繁困扰着工程团队&#xff1a;为什么训练时表现优异的模型&#xff0c;上线后总是“卡顿”&#xff1f;用户提问3秒得不…

作者头像 李华
网站建设 2026/4/21 14:40:52

终极指南:如何用Scratch零代码实现AI项目

终极指南&#xff1a;如何用Scratch零代码实现AI项目 【免费下载链接】ml2scratch 機械学習 x スクラッチ(Connect Machine Learning with Scratch) 项目地址: https://gitcode.com/gh_mirrors/ml/ml2scratch 还在为复杂的机器学习算法而烦恼吗&#xff1f;现在&#xf…

作者头像 李华
网站建设 2026/4/28 10:42:38

Skopeo实战手册:轻松玩转容器镜像管理

Skopeo实战手册&#xff1a;轻松玩转容器镜像管理 【免费下载链接】skopeo Work with remote images registries - retrieving information, images, signing content 项目地址: https://gitcode.com/GitHub_Trending/sk/skopeo 还在为复杂的容器镜像操作而烦恼吗&#…

作者头像 李华
网站建设 2026/4/27 9:40:54

Intel RealSense D405深度相机标定实战:从入门到精通的完整指南

Intel RealSense D405深度相机标定实战&#xff1a;从入门到精通的完整指南 【免费下载链接】librealsense Intel RealSense™ SDK 项目地址: https://gitcode.com/GitHub_Trending/li/librealsense 深度相机标定是三维测量和计算机视觉应用的基础&#xff0c;Intel Rea…

作者头像 李华
网站建设 2026/4/28 18:10:09

如何用AI神器自动搞定B站直播录播?这份完整指南让你彻底解放双手

如何用AI神器自动搞定B站直播录播&#xff1f;这份完整指南让你彻底解放双手 【免费下载链接】bilive 极快的B站直播录制、自动切片、自动渲染弹幕以及字幕并投稿至B站&#xff0c;兼容超低配置机器。 项目地址: https://gitcode.com/gh_mirrors/bi/bilive 还在为手动录…

作者头像 李华