当前位置: 首页 > article >正文

桥接模式 Bridge Pattern

桥接模式Abstraction Implementor 的理解

在图书馆看到一本 通过电商项目真正实战《贯穿设计模式》。拿起来翻到了 桥接模式,感觉味道不对,和我印象中不一样。

感谢这位同学提供的源码

贯穿设计模式-适配器模式+桥接模式_-CSDN博客GitHub - WeiXiao-Hyy/design-patterns: 《贯穿设计模式》学习笔记

Clone下来生成如下 Class Diagram。

和wikipedia 上的 桥接模式类图(下图),对比一下就发现,书的作者对桥接模式的运用有点儿“独特风格”。似乎认为 abstraction 和 implementor 是同一个纬度,而同一纬度并不适合桥接模式。

Abstraction (abstract class)  【(抽象类)】

        defines the abstract interface 【定义抽象的接口】

        maintains the Implementor reference.  【持有一个Implementor 的引用】

RefinedAbstraction (normal class)    【(普通类)】

        extends the interface defined by Abstraction  【扩展了 Abstraction 功能】

Implementor (interface)      【实施者(接口)】

        defines the interface for implementation classes  【给 ConcreteImplementor 定义接口】

ConcreteImplementor (normal class)    【具体实施者(普通类)】

        implements the Implementor interface 【实现 Implementor 接口】

刚接触的桥接模式时,觉得很难理解,现在想想其实是对  Abstraction 和 Implementor 的理解出了问题。

DeepSeek 给的解释是:

  • 抽象类(Abstraction):定义高层逻辑,并持有一个对实现类的引用。

  • 扩展抽象类(Refined Abstraction):对抽象类的扩展,通常增加更多的功能。

  • 实现类接口(Implementor):定义实现部分的接口,抽象类通过该接口调用具体的实现。

  • 具体实现类(Concrete Implementor):实现实现类接口,提供具体的实现细节。

第一次看了,会不会觉得这里的 “实现类 Implementor” 就是这里 “抽象类 Abstraction” 的实现呢!如果这么认为就无法理解 bridge pattern了。并非java中的抽象类和实现类。

Abstraction 和 Implementor 的关系

  • 分离抽象与实现:Abstraction 和 Implementor 是两个独立的维度,Abstraction 依赖于 Implementor 的接口,但不需要知道具体的实现细节。

  • 组合关系:Abstraction 通过组合的方式持有一个 Implementor 的引用,并将具体的操作委托给 Implementor。

  • 独立变化:Abstraction 和 Implementor 可以独立扩展和修改,而不会相互影响。

对的,是组合关系,并非继承 🤣,而且是两个纬度。

这里推荐 设计模式之桥接模式(Bridge)-CSDN博客 中的支付工具和支付方式的例子。

来看一个 Pizza 的例子

在一个地方,开了一家Pizza店, 有两个不同的口味。

        PepperoniPizza extends Pizza 

        VeggiePizza extends Pizza

生意不错,分别在美国和意大利开了店,根据店铺 和 口味,两个维度,扩展到 4个 Pizza 实现。

        ItalianVeggiePizza extends Pizza

        ItalianPepperoniPizza extends Pizza

        AmericanVeggiePizza extends Pizza

        AmericanPepperoniPizza extends Pizza

后续如果增加 Chicken Pizza,则要同时增加两种实现。 无法相信随着口味和店铺的扩增,将会成倍增长。

导致此问题的原因是我们尝试从两个不同的维度扩展 pizza 。解决此问题则需要采用 组合(composition) 而非 继承(inheritance)。

也就是说需要,提取其中一个纬度,采用不同的 class hierarchy。原有的class持有新的 hierarchy 的引用。

通过这种方式,我们需要 定义 Restaurant abstract class,提供 ItalianRestaurant 和 AmericanRestaurant 两个实现类。Pizza 对象引用则被 Restaurant 持有,来充当 bridge。

AmericanRestaurant americanRestaurant = new AmericanRestaurant(new PepperoniPizza());
americanRestaurant.deliver();ItalianRestaurant italianRestaurant = new ItalianRestaurant(new VeggiePizza());
italianRestaurant.deliver();

DeepSeek给出的解释 

桥接模式(Bridge Pattern)是一种结构型设计模式,旨在将抽象部分与实现部分分离,使它们可以独立变化。为了更好地理解桥接模式,可以从以下几个方面入手:

1. 核心思想

桥接模式的核心在于解耦。它将抽象部分(通常是高层逻辑)与实现部分(通常是底层细节)分离,使它们可以独立扩展和修改,而不会相互影响。

2. 适用场景

  • 当你有多个维度的变化时,桥接模式可以帮助你避免类爆炸问题。

  • 当你希望抽象部分和实现部分可以独立扩展时。

  • 当你希望在运行时切换实现部分时。

3. 结构

桥接模式通常包含以下角色:

  • 抽象类(Abstraction):定义高层逻辑,并持有一个对实现类的引用。

  • 扩展抽象类(Refined Abstraction):对抽象类的扩展,通常增加更多的功能。

  • 实现类接口(Implementor):定义实现部分的接口,抽象类通过该接口调用具体的实现。

  • 具体实现类(Concrete Implementor):实现实现类接口,提供具体的实现细节。

4. 示例

假设你有一个图形绘制系统,支持多种形状(如圆形、矩形)和多种颜色(如红色、蓝色)。如果不使用桥接模式,你可能需要为每种形状和颜色的组合创建一个类(如红色圆形、蓝色矩形等),这会导致类爆炸。

使用桥接模式,你可以将形状和颜色分离:

  • 抽象类:形状(Shape)

  • 扩展抽象类:圆形(Circle)、矩形(Rectangle)

  • 实现类接口:颜色(Color)

  • 具体实现类:红色(Red)、蓝色(Blue) 

// 实现类接口
interface Color {void applyColor();
}// 具体实现类
class Red implements Color {@Overridepublic void applyColor() {System.out.println("Applying red color");}
}class Blue implements Color {@Overridepublic void applyColor() {System.out.println("Applying blue color");}
}// 抽象类
abstract class Shape {protected Color color;public Shape(Color color) {this.color = color;}abstract void draw();
}// 扩展抽象类
class Circle extends Shape {public Circle(Color color) {super(color);}@Overridevoid draw() {System.out.print("Drawing Circle: ");color.applyColor();}
}class Rectangle extends Shape {public Rectangle(Color color) {super(color);}@Overridevoid draw() {System.out.print("Drawing Rectangle: ");color.applyColor();}
}// 客户端代码
public class BridgePatternDemo {public static void main(String[] args) {Shape redCircle = new Circle(new Red());Shape blueRectangle = new Rectangle(new Blue());redCircle.draw();blueRectangle.draw();}
}

5. 优点

  • 解耦:抽象和实现可以独立变化,互不影响。

  • 扩展性:可以轻松扩展新的抽象类或实现类。

  • 减少类爆炸:避免了为每个组合创建单独的类。

6. 缺点

  • 复杂性增加:引入了更多的类和接口,增加了系统的复杂性。

  • 理解难度:对于初学者来说,桥接模式可能较难理解。

7. 与其他模式的关系

  • 与适配器模式:适配器模式通常用于使不兼容的接口兼容,而桥接模式用于将抽象与实现分离。

  • 与策略模式:策略模式侧重于算法的替换,而桥接模式侧重于抽象与实现的分离。

8. 总结

桥接模式通过将抽象与实现分离,提供了一种灵活的方式来处理多维度的变化。理解桥接模式的关键在于认识到它的解耦思想,并通过实际例子来体会其应用场景和优势。

相关文章:

桥接模式 Bridge Pattern

桥接模式Abstraction 和 Implementor 的理解 在图书馆看到一本 通过电商项目真正实战《贯穿设计模式》。拿起来翻到了 桥接模式,感觉味道不对,和我印象中不一样。 感谢这位同学提供的源码 贯穿设计模式-适配器模式桥接模式_-CSDN博客GitHub - WeiXiao…...

C# SpinLock 类 使用详解

总目录 前言 SpinLock 是 C# 中一种轻量级的自旋锁,属于 System.Threading 命名空间,专为极短时间锁竞争的高性能场景设计。它通过忙等待(自旋)而非阻塞线程来减少上下文切换开销,适用于锁持有时间极短(如…...

Ubuntu 安装 OpenCV (C++)

版本详情: Ubuntu: 22.04 5.15.0-133-generic gcc: 11.4.0 g: 11.4.0 OpenCV: 4.7.0 1. 卸载 OpenCV 进入原先编译 opencv 的 build 目录,在该目录下打开终端,执行以下代码(如果 build 已经删除了,可以重新编译一…...

推荐两个比较好用的流程图js库

React Flow 和 Logic Flow 是两个用于构建流程图的 JavaScript 库,适用于不同的场景和需求。以下是它们的简要介绍和对比: React Flow React Flow 是一个基于 React 的流程图库,专注于构建高度可定制的节点和边。它适用于需要复杂交互和数据…...

前端模板引擎

前言 正常渲染拿到数据后渲染&#xff0c;三步走&#xff1a;格式化数据、编译模板、渲染数据 如下例 <!DOCTYPE html><html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice…...

Linux /dev/null

/dev/null 是 Linux 和类 Unix 系统中一个特殊且非常有用的设备文件&#xff0c;也被称为空设备。下面为你详细介绍它的特点、用途和使用示例。 特点 写入丢弃&#xff1a;当向 /dev/null 写入数据时&#xff0c;这些数据会被立即丢弃&#xff0c;不会被保存到任何地方&#…...

ubuntu安装docker 无法拉取问题

sudo docker run hello-world [sudo] ubuntu 的密码&#xff1a; Unable to find image hello-world:latest locally docker: Error response from daemon: Get "https://registry-1.docker.io/v2/": context deadline exceeded (Client.Timeout exceeded while awai…...

深入理解Kubernetes:容器编排的中流砥柱

Kubernetes容器编排 在云原生技术蓬勃发展的当下&#xff0c;Kubernetes&#xff08;简称K8s&#xff09;已成为容器编排领域的事实标准&#xff0c;为现代应用的部署、管理与扩展提供了强大支持。 K8s的核心优势之一是其卓越的容器编排能力 在传统应用部署模式下&#xff0c;…...

长尾词SEO优化软件:企业官网流量提升的软件【实测】

搜索引擎流量中68%来自长尾关键词&#xff08;数据来源&#xff1a;Ahrefs 2025&#xff09;&#xff0c;但83%企业仍困于「高价值长尾词难挖掘内容生产跟不上」的双重困境。当同行用智能工具批量布局「孕妇防辐射服哪个牌子好」等精准词时&#xff0c;手动分析数据的你可能还在…...

用自己的数据训练yolov11目标检测

文章目录 概要理论知识整体架构流程架构优化多任务支持多参数体量 操作实操环境配置数据准备数据标注数据放置路径 训练预测 概要 YOLOv11 是 Ultralytics 团队于 2024 年 9 月 30 日发布的最新目标检测模型&#xff0c;延续了 YOLO 系列实时推理特性&#xff0c;同时通过架构优…...

gsoap实现webservice服务

gsoap实现webservice服务 在实现Web服务时&#xff0c;使用gSOAP是一个很好的选择&#xff0c;因为它提供了强大的工具和库来创建SOAP和RESTful服务。gSOAP是一个C和C语言开发的库&#xff0c;它支持SOAP协议的各种版本&#xff0c;包括SOAP 1.1和SOAP 1.2。下面是如何使用gSO…...

相比于WebSocket,SSE更适合轻量级

一、 前言 项目首页有一个待办任务数量和消息提醒数量的展示&#xff08;单向数据的展示 &#xff09;&#xff0c;之前使用了定时器&#xff0c;每隔十秒钟发送一次请求到后端接口拿数据&#xff0c;这也就是我们常说的轮询做法。 1. 轮询的缺点 我们都知道轮询的缺点有几种…...

项目2 数据可视化--- 第十五章 生成数据

数据分析是使用代码来探索数据内的规律和关联。 数据可视化是通过可视化表示来 探索和呈现数据集内的规律。 好的数据可视化&#xff0c;可以发现数据集中未知的规律和意义。 一个流行的工具是Matplotlib&#xff0c;他是一个数据绘图库&#xff1b; 还有Plotly包&#xff…...

【Maven私服配置】

Maven私服配置 对于一些中央的pom&#xff0c;应该配置对应的mirror镜像访问 <mirrors> <mirror> <id>alimaven</id> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <mirr…...

QT (四)模型/视图 QFileSystemModel,QStringListModel,QStandardItemModel

思考&#xff1a;QTableWidget 在某种程度上可以等价为QStandardItemModel&#xff0c;同理&#xff0c;其他的功能也有类似的等价&#xff0c;但是以当前的QTableWidget 和QStandardItemModel为例的话&#xff0c;两者都是用于实现建立表格的相关组件&#xff0c;只不过QStand…...

BSD实现:单播

分用单播数据报 如果程序执行到这里&#xff0c;说明程序并没有执行多播操作&#xff0c;那么大概率是单播。 维护缓存指针 udp_last_inpcb是上一次接收数据报的端口的控制块指针&#xff0c;维护该指针的依据是许多程序往往具有时间局部性&#xff0c;也就是&#xff1a;经…...

. Unable to find a @SpringBootConfiguration(默认软件包中的 Spring Boot 应用程序)

解决&#xff1a; 新建一个包即可 问题&#xff1a; 默认软件包中的 Spring Boot 应用程序。 原因&#xff1a; 默认包的定义 &#xff1a; 如果一个 Java 类没有使用 package 声明包名&#xff0c;则该类会被放置在默认包中。Spring Boot 遵循 Java 的包管理约定&#xff…...

【前端知识】浏览器兼容方案polyfill

浏览器兼容方案polyfill 什么是 Polyfill&#xff1f;Polyfill 的作用Polyfill 的工作原理1. **特性检测**2. **加载 Polyfill**3. **模拟实现** Polyfill 的常见场景Polyfill 的使用方式Polyfill 的优缺点优点缺点 常见的 Polyfill 库总结 什么是 Polyfill&#xff1f; Polyf…...

互信息的定义与公式

互信息 定义公式 从条件熵中我们知道&#xff0c;当获取的信息和要研究的食物”有关系时“&#xff0c;这些信息才能帮助我们消除不确定性。如何衡量获取信息和要研究事物“有关系”呢&#xff1f;比如常识告诉我们&#xff0c;一个随机事件“今天深圳下雨”和另一个随机事件“…...

(算法基础——树)——python树结构使用指南

1. 树的定义与实现 树是一种非线性数据结构&#xff0c;常用于解决层次化数据问题&#xff08;如路径搜索、二叉树遍历等&#xff09;。以下是树的两种常见实现方式&#xff1a; (1) 类&#xff08;Class&#xff09;实现 class TreeNode:def __init__(self, val0, leftNone…...

【小白学AI系列】NLP 核心知识点(七)Embedding概念介绍

Embedding&#xff08;嵌入&#xff09; 是自然语言处理&#xff08;NLP&#xff09;中非常重要的概念。简单来说&#xff0c;embedding 是一种将离散的、稀疏的、不可直接计算的对象&#xff08;比如词、字符或句子&#xff09;转换为 密集的、连续的向量表示 的技术。 这个向…...

Android adb测试常用命令大全

目录 一、查看最上层成activity名字: 二、查看Activity的任务栈&#xff1a; 三、获取安装包信息 四、性能相关 1、显示CPU信息 : 2、查看CPU使用信息 3、内存信息&#xff08;meminfo package_name or pid 使用程序的包名或者进程id显示内存信息&#xff09; 4、电量信…...

FRRouting配置与OSPF介绍,配置,命令,bfd算法:

文章目录 1、frrouting的配置&#xff1a;2、ospf2.1、检测和维护邻居关系2.2、ospfDR和BDR2.3、odpf邻居表2.4、ospf常用命令2.5、bfd配置 1、frrouting的配置&#xff1a; sudo service zebra start sudo service ospfd start telnet localhost 2604 en configure termina…...

【MyBatis】预编译SQL与即时SQL

目录 1. 以基本类型参数为例测试#{ }与${ }传递参数的区别 1.1 参数为Integer类型 1.2 参数为String类型 2. 使用#{ }传参存在的问题 2.1 参数为排序方式 2.2 模糊查询 3. 使用${ }传参存在的问题 3.1 SQL注入 3.2 对比#{ } 与 ${ }在SQL注入方面存在的问题 3.3 预编译…...

prometheus、grafana、windows、node exporter 安装包

开发过程中应用到的安装包软件&#xff1a; prometheus-2.20.0.windows-amd64.tar.gz windows_exporter-0.13.0-amd64.exe grafanawindows-x64.zip influxdb-1.7.0_windows_amd64.zip 我用夸克网盘分享了「prometheus、grafana、windows、node exporter 安装包」&#xff…...

Python数据可视化 - Matplotlib教程

文章目录 前言一、Matplotlib简介及安装1. Matplotlib简介2. 安装Matplotlib 二、Matplotlib Pyplot1. Pyplot介绍2. Pyplot中方法介绍2.1 创建和管理图形2.2 绘制图形2.3 设置图形属性2.4 保存和展示 三、Matplotlib绘图标记1. 介绍2. 基本用法3. 标记大小与颜色4. 标记样式列…...

DeepSeek R1 与 OpenAI O1:机器学习模型的巅峰对决

我的个人主页 我的专栏&#xff1a;人工智能领域、java-数据结构、Javase、C语言&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01;点赞&#x1f44d;收藏❤ 一、引言 在机器学习的广袤天地中&#xff0c;大型语言模型&#xff08;LLM&#xff09;无疑是最…...

内容中台重构企业内容管理流程驱动智能协作升级

内容概要 内容中台作为企业数字化转型的核心基础设施&#xff0c;通过技术架构革新与功能模块整合&#xff0c;重构了传统内容管理流程的底层逻辑。其核心价值在于构建动态化、智能化的内容生产与流转体系&#xff0c;将分散的创作、存储、审核及分发环节纳入统一平台管理。基…...

STM32 Flash详解教程文章

目录 Flash基本概念理解 Flash编程接口FPEC Flash擦除/写入流程图 Flash选项字节基本概念理解 Flash电子签名 函数读取地址下存放的数据 Flash的数据处理限制部分 编写不易&#xff0c;请勿搬运&#xff0c;感谢理解&#xff01;&#xff01;&#xff01; Flash基本概念…...

小米 R3G 路由器刷机教程(Pandavan)

小米 R3G 路由器刷机教程&#xff08;Pandavan&#xff09; 一、前言 小米 R3G 路由器以其高性价比和稳定的性能备受用户青睐。然而&#xff0c;原厂固件的功能相对有限&#xff0c;难以满足高级用户的个性化需求。刷机不仅可以解锁路由器的潜能&#xff0c;还能通过第三方固…...