设计模式-结构型-桥接模式

news2025/1/11 4:11:28

1. 什么是桥接模式?

桥接模式(Bridge Pattern) 是一种结构型设计模式,它旨在将抽象部分与实现部分分离,使它们可以独立变化。通过这种方式,系统可以在抽象和实现两方面进行扩展,而无需相互影响。

核心思想

桥接模式的核心思想是将抽象实现解耦,使得它们可以独立扩展。它通过引入一个“桥接接口”,在抽象层和实现层之间建立一个桥梁。

适用场景

桥接模式适用于以下场景:

  1. 需要在两个维度上扩展:比如图形与颜色、设备与操作系统等。
  2. 避免类的数量爆炸:当类的组合维度过多时,使用桥接模式可以避免创建大量的子类。
  3. 希望实现抽象和具体实现分离:提高系统的灵活性和可维护性。

2. 桥接模式的结构

UML 类图

图像来源

核心角色

  1. Abstraction(抽象类)
    定义抽象部分的接口,包含一个指向实现部分 Implementor 的引用。

  2. RefinedAbstraction(扩充抽象类)
    继承自 Abstraction,扩展其功能。

  3. Implementor(实现接口)
    定义实现部分的接口,通常为抽象接口,供具体实现类实现。

  4. ConcreteImplementor(具体实现类)
    实现 Implementor 接口,完成具体操作。


3. 桥接模式的示例

场景描述

假设我们需要设计一个绘图系统,支持不同类型的形状(如圆形和矩形)以及不同颜色的渲染方式(如红色和蓝色)。如果直接使用继承,可能需要创建大量子类(如红色圆形、蓝色矩形等),桥接模式可以优雅地解决这个问题。

代码实现

# 实现部分:定义颜色
class Color:
    def apply_color(self):
        pass

class RedColor(Color):
    def apply_color(self):
        return "Red"

class BlueColor(Color):
    def apply_color(self):
        return "Blue"

# 抽象部分:定义形状
class Shape:
    def __init__(self, color: Color):
        self.color = color

    def draw(self):
        pass

class Circle(Shape):
    def __init__(self, color: Color, radius: int):
        super().__init__(color)
        self.radius = radius

    def draw(self):
        return f"Drawing Circle of radius {self.radius} with color {self.color.apply_color()}"

class Rectangle(Shape):
    def __init__(self, color: Color, width: int, height: int):
        super().__init__(color)
        self.width = width
        self.height = height

    def draw(self):
        return f"Drawing Rectangle of width {self.width} and height {self.height} with color {self.color.apply_color()}"

# 测试桥接模式
if __name__ == "__main__":
    # 创建颜色实例
    red = RedColor()
    blue = BlueColor()

    # 创建形状实例
    red_circle = Circle(red, 10)
    blue_rectangle = Rectangle(blue, 20, 15)

    print(red_circle.draw())      # 输出:Drawing Circle of radius 10 with color Red
    print(blue_rectangle.draw()) # 输出:Drawing Rectangle of width 20 and height 15 with color Blue

4. 桥接模式的优缺点

优点

  1. 解耦抽象和实现
    抽象部分与实现部分可以独立变化,增强系统的灵活性。

  2. 提高可扩展性
    可以轻松增加新的抽象部分或实现部分,而无需修改已有代码。

  3. 符合开闭原则
    新增功能时,只需扩展新的类,而不需要修改现有代码。

  4. 减少类的数量
    避免了多维度继承导致的类爆炸问题。

缺点

  1. 复杂性增加
    系统需要引入额外的桥接接口和实现层,增加了代码的复杂性。

  2. 过度设计
    对于简单需求可能显得冗余,不如直接使用继承。


5. 桥接模式的应用场景

现实应用

  1. 图形绘制系统
    如上述示例中的形状与颜色的组合。

  2. 跨平台应用
    一个程序需要适配不同平台时,抽象部分定义通用接口,具体实现部分针对各个平台实现。

  3. 数据库访问
    抽象部分定义通用的数据操作接口,具体实现部分可以是 MySQL、PostgreSQL、MongoDB 等不同数据库的操作实现。

  4. 日志框架
    日志内容与日志存储方式分离,方便扩展。


6. 总结

桥接模式通过将抽象与实现分离,使得系统的两个维度可以独立扩展。这种模式在需要跨维度组合的场景中尤为适用。通过桥接模式,我们可以有效地降低代码的耦合度,提高系统的灵活性和可维护性。

核心要点

  1. 抽象部分与实现部分分离
  2. 避免多维度继承引发的类爆炸问题
  3. 灵活扩展,符合开闭原则

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

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

相关文章

python学习笔记—16—数据容器之元组

1. 元组——tuple(元组是一个只读的list) (1) 元组的定义注意:定义单个元素的元组,在元素后面要加上 , (2) 元组也支持嵌套 (3) 下标索引取出元素 (4) 元组的相关操作 1. index——查看元组中某个元素在元组中的位置从左到右第一次出现的位置 t1 (&qu…

基础算法--查找

一、线性枚举 1、线性枚举定义 线性枚举指的就是遍历某个一维数组(顺序表)的所有元素,找到满足条件的那个元素并且返回,返回值可以是下标,也可以是元素本身。 由于是遍历的,穷举了所有情况,所…

G1垃圾回收器的FullGC

如何确定GarbageFirst回收器发生的是FullGC ? 必须出现FullGC字样才算是FUllGC,例如下图:因为内存分配失败(Allocation Failure)导致 如果不出现FullGC的字样说明它不是FUllGC,并不像Serial GC、ParallelGC的在老年代…

Golang的代码压缩技术应用案例分析与研究实践

Golang的代码压缩技术应用案例分析与研究实践 一、介绍 是一种具有强大性能和便捷开发特性的编程语言,除了其优秀的语法和标准库外,它还拥有很多高级特性,其中之一就是代码压缩技术。本文将从常见的Golang代码压缩技术应用案例出发&#xff0…

【Uniapp-Vue3】image媒体组件属性

如果我们想要在页面上展示图片就需要使用到image标签。 这部分最重要的是图片的裁剪,图片的裁剪和缩放属性: mode 图片裁剪、缩放的模式 默认值是scaleToFill 我将用两张图片对属性进行演示,一张是pic1.jpg(宽更长&#xf…

【网络协议】交换机概念与配置(第一部分)

概述 本文将探讨交换机的概念以及交换机的基础配置,并以此引入对 VLAN 的讨论。 文章目录 概述CSMA/CD以太网通信单播(Unicast)多播(Multicast)广播(Broadcast) MAC 地址以太网中的双工设置半双…

oracle位运算、左移右移、标签算法等

文章目录 位运算基础与或非同或同或应用场景 异或异或应用场景 什么是真值表 oracle基础函数创建bitor(按位或)函数bitnot(按位非)函数bitxor(按位异或)函数左移函数BITSHIFT()函数(实测不可用,废弃掉该方案)右移函数(略,有此场景吗?) 实际应用资质字典…

(五)ROS通信编程——参数服务器

前言 参数服务器在ROS中主要用于实现不同节点之间的数据共享(P2P)。参数服务器相当于是独立于所有节点的一个公共容器,可以将数据存储在该容器中,被不同的节点调用,当然不同的节点也可以往其中存储数据,关…

《零基础Go语言算法实战》【题目 1-18】切片的反转

《零基础Go语言算法实战》 【题目 1-18】切片的反转 请编写一个名为 reverse 的函数,采用整数切片并在不使用临时切片的情况下将切片反转。 【解答】 可以通过 for 循环交换切片中每个元素的值,使其从左向右滑动。最终,所有元素都将 被反转。…

Elasticsearch:搜索相关性

这里写目录标题 一、相关性的概述二、自定义评分策略1、TF-IDF算法2、BM25算法 三、自定义评分策略1、Index Boost:在索引层面修改相关性2、boosting:修改文档相关性3、negative_boost:降低相关性4、function_score:自定义评分5、…

【C++经典例题】求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句

💓 博客主页:倔强的石头的CSDN主页 📝Gitee主页:倔强的石头的gitee主页 ⏩ 文章专栏: 期待您的关注 题目描述: 原题链接: 求123...n_牛客题霸_牛客网 (nowcoder.com) 解题思路: …

淺談Cocos2djs逆向

前言 簡單聊一下cocos2djs手遊的逆向,有任何相關想法歡迎和我討論^^ 一些概念 列出一些個人認為比較有用的概念: Cocos遊戲的兩大開發工具分別是CocosCreator和CocosStudio,區別是前者是cocos2djs專用的開發工具,後者則是coco…

概率论与数理统计总复习

复习课本:中科大使用的教辅《概率论和数理统计》缪柏其、张伟平版本 目录 0.部分积分公式 1.容斥原理 2.条件概率 3.全概率公式 4.贝叶斯公式 5.独立性 6.伯努利分布(两点分布) 7.二项分布 8.帕斯卡分布(负二项分布&am…

el-table自定义按钮控制扩展expand

需求:自定义按钮实现表格扩展内容的展开和收起,实现如下: 将type“expand”的表格列的宽度设置为width"1",让该操作列不展示出来,然后通过ref动态调用组件的内部方法toggleRowExpansion(row, row.expanded)控…

大语言模型训练的数据集从哪里来?

继续上篇文章的内容说说大语言模型预训练的数据集从哪里来以及为什么互联网上的数据已经被耗尽这个说法并不专业,再谈谈大语言模型预训练数据集的优化思路。 1. GPT2使用的数据集是WebText,该数据集大概40GB,由OpenAI创建,主要内…

【C++习题】22.随机链表的复制

文章目录 题目:138. 随机链表的复制 - 力扣(LeetCode)代码: 题目:138. 随机链表的复制 - 力扣(LeetCode) 链接🔗:138. 随机链表的复制 - 力扣(LeetCode&…

C# 或 .NetCore 如何使用 NPOI 导出图片到 Excel 文件

今天在本文中,我们将尝试使用NPOI库将图像插入到 Excel 文件的特定位置。请将以下逻辑添加到您的写作方法中,在 Excel 文件中添加图像(JPEG、PNG),我已经有一个示例 jpeg 文件 - Read-write-excel-npoi.jpg ,我们将尝试…

Photon最新版本PUN 2.29 PREE,在无网的局域网下,无法连接自己搭建的本地服务器

1.图1为官方解答 2.就是加上这一段段代码:PhotonNetwork.NetworkingClient.SerializationProtocol SerializationProtocol.GpBinaryV16; 完美解决 unity 商店最新PUN 2 插件 不能连接 (环境为:本地局域网 无外网情况 ) …

Python 爬虫验证码识别

在我们进行爬虫的过程中,经常会碰到有些网站会时不时弹出来验证码识别。我们该如何解决呢?这里分享 2 种我尝试过的方法。 0.验证码示例 1.OpenCV pytesseract 使用 Python 中的 OpenCV 库进行图像预处理(边缘保留滤波、灰度化、二值化、…

【Rust自学】10.7. 生命周期 Pt.3:输入输出生命周期与3规则

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 10.7.1. 深入理解生命周期 1.指定生命周期参数的方式依赖于函数所做的事情 以上一篇文章的代码为例子&#xff1a; fn longest<a&g…