桥接模式 Bridge Pattern

news2025/3/31 19:56:09

桥接模式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 {
    @Override
    public void applyColor() {
        System.out.println("Applying red color");
    }
}

class Blue implements Color {
    @Override
    public 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);
    }

    @Override
    void draw() {
        System.out.print("Drawing Circle: ");
        color.applyColor();
    }
}

class Rectangle extends Shape {
    public Rectangle(Color color) {
        super(color);
    }

    @Override
    void 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. 总结

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

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 已经删除了,可以重新编译一…

前端模板引擎

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

长尾词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…

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

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

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

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

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

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

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 预编译…

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;还能通过第三方固…

红队视角出发的k8s敏感信息收集——Kubernetes API 扩展与未授权访问

针对 Kubernetes API 扩展与未授权访问 的详细攻击视角分析&#xff0c;聚焦 Custom Resource Definitions (CRD) 和 Aggregated API Servers 的潜在攻击面及利用方法&#xff1a; ​ 攻击链示例 1. 攻击者通过 ServiceAccount Token 访问集群 → 2. 枚举 CRD 发现数据库配…

11. Docker 微服务实战(将项目打包生成镜像,在 Docker 当中作为容器实例运行)

11. Docker 微服务实战(将项目打包生成镜像&#xff0c;在 Docker 当中作为容器实例运行) 文章目录 11. Docker 微服务实战(将项目打包生成镜像&#xff0c;在 Docker 当中作为容器实例运行)2. 最后&#xff1a; 建 Module - docker_boot 编辑 pom <?xml version"1.0&…

计算机视觉:卷积神经网络(CNN)基本概念(二)

第一章&#xff1a;计算机视觉中图像的基础认知 第二章&#xff1a;计算机视觉&#xff1a;卷积神经网络(CNN)基本概念(一) 第三章&#xff1a;计算机视觉&#xff1a;卷积神经网络(CNN)基本概念(二) 第四章&#xff1a;搭建一个经典的LeNet5神经网络 接上一篇《计算机视觉&am…

【数据结构-红黑树】

文章目录 红黑树红黑树介绍红黑树的五个基本性质红黑树的平衡原理红黑树的操作红黑树的操作 代码实现节点实现插入和查询操作 红黑树 红黑树介绍 红黑树&#xff08;Red-Black Tree&#xff09;是一种自平衡的二叉查找树&#xff08;Binary Search Tree, BST&#xff09;&…

dify.ai 配置链接到阿里云百练等云厂商的 DeepSeek 模型

要将 dify.ai 配置链接到阿里云百练等云厂商的 DeepSeek 模型. 申请阿里云百练的KEY 添加模型 测试模型