Golang学习笔记_33——桥接模式

Golang学习笔记_30——建造者模式
Golang学习笔记_31——原型模式
Golang学习笔记_32——适配器模式


文章目录

  • 桥接模式详解
    • 一、桥接模式核心概念
      • 1. 定义
      • 2. 解决的问题
      • 3. 核心角色
      • 4. 类图
    • 二、桥接模式的特点
    • 三、适用场景
      • 1. 多维度变化
      • 2. 跨平台开发
      • 3. 动态切换实现
    • 四、与其他结构型模式的对比
    • 五、Go 语言代码示例
    • 六、桥接模式的高级用法
      • 1. 多维度组合
      • 2. 动态切换实现
    • 七、总结


桥接模式详解

一、桥接模式核心概念

1. 定义

桥接模式是一种 结构型设计模式,通过 将抽象部分与实现部分分离,使它们可以独立变化。它通过组合关系替代继承关系,解决多维度的扩展问题。

2. 解决的问题

  • 多维度变化:当系统存在多个独立变化的维度时(如形状和颜色),避免类爆炸问题。
  • 灵活扩展:允许抽象和实现部分独立扩展,无需修改原有代码。
  • 降低耦合:通过组合关系替代继承,减少类之间的强依赖。

3. 核心角色

  1. Abstraction(抽象化):定义高层抽象接口,维护对实现化对象的引用。
  2. RefinedAbstraction(扩展抽象化):对抽象化的扩展,提供更精细的控制。
  3. Implementor(实现化):定义实现类的接口,提供基础操作。
  4. ConcreteImplementor(具体实现化):实现接口的具体类。

4. 类图

桥接模式类图

示例类图

二、桥接模式的特点

优点

  1. 解耦抽象与实现
    抽象层和实现层独立变化,提高系统灵活性。
  2. 扩展性强
    新增维度只需添加对应实现类,无需修改现有代码。
  3. 符合开闭原则
    对扩展开放,对修改关闭。

缺点

  1. 设计复杂度增加
    需要正确识别系统中独立变化的维度。
  2. 理解成本高
    组合关系比继承更难直观理解。

三、适用场景

1. 多维度变化

  • 示例:图形绘制系统(形状 × 颜色 × 渲染引擎)
  • 解决:将形状作为抽象,颜色和渲染作为独立实现。

2. 跨平台开发

  • 示例:支持 Android/iOS 的 UI 组件库
  • 解决:UI 组件抽象与平台具体实现分离。

3. 动态切换实现

  • 示例:数据库驱动切换(MySQL/PostgreSQL)
  • 解决:通过桥接接口动态替换底层实现。

四、与其他结构型模式的对比

模式核心目标关键区别
适配器解决接口不兼容问题关注接口转换,通常在系统设计后期使用
组合处理树形结构强调部分与整体的层次关系
桥接分离抽象与实现关注多维度的独立扩展

五、Go 语言代码示例

场景描述
实现跨平台图形渲染系统,支持不同形状(圆形/矩形)在不同平台(Windows/Linux)的绘制。

代码实现

package bridgedemoimport "fmt"// Renderer 渲染器接口
type Renderer interface {RenderCircle(radius float32)RenderRectangle(width, height float32)
}// WindowsRenderer windows渲染器实现
type WindowsRenderer struct{}func (w *WindowsRenderer) RenderCircle(radius float32) {// 渲染windows矩形的实现fmt.Printf("windows render circle: radius = %f\n", radius)
}func (w *WindowsRenderer) RenderRectangle(width, height float32) {// 渲染Windows矩形的实现fmt.Printf("windows render rectangle: width = %f, height = %f\n", width, height)
}// LinuxRenderer linux渲染器实现
type LinuxRenderer struct{}func (l *LinuxRenderer) RenderCircle(radius float32) {// 渲染Linux圆形的实现fmt.Printf("linux render circle: radius = %f\n", radius)
}func (l *LinuxRenderer) RenderRectangle(width, height float32) {// 渲染Linux矩形的实现fmt.Printf("linux render rectangle: width = %f, height = %f\n", width, height)
}// Shape 图形接口
type Shape interface {Draw()
}// Circle 圆形
type Circle struct {Radius   float32Renderer Renderer
}func NewCircle(radius float32, renderer Renderer) *Circle {return &Circle{Radius:   radius,Renderer: renderer,}
}func (c *Circle) Draw() {c.Renderer.RenderCircle(c.Radius)
}// Rectangle 矩形
type Rectangle struct {Width    float32Height   float32Renderer Renderer
}func newRectangle(width, height float32, renderer Renderer) *Rectangle {return &Rectangle{Width:    width,Height:   height,Renderer: renderer,}
}func (r *Rectangle) Draw() {r.Renderer.RenderRectangle(r.Width, r.Height)
}func test() {// 创建Windows渲染器windowsRenderer := &WindowsRenderer{}// 创建Linux渲染器linuxRenderer := &LinuxRenderer{}// 创建跨平台图形shapes := []Shape{NewCircle(5.0, windowsRenderer),NewCircle(8.0, linuxRenderer),newRectangle(10.0, 20.0, windowsRenderer),newRectangle(15.0, 25.0, linuxRenderer),}// 绘制图形for _, shape := range shapes {shape.Draw()}
}

输出结果

=== RUN   Test_test
windows render circle: radius = 5.000000
linux render circle: radius = 8.000000
windows render rectangle: width = 10.000000, height = 20.000000
linux render rectangle: width = 15.000000, height = 25.000000
--- PASS: Test_test (0.00s)
PASS

六、桥接模式的高级用法

1. 多维度组合

// 添加颜色维度
type ColorImplementor interface {SetColor(color string)
}type ColoredShape struct {shape  Shapecolor  string
}func (c *ColoredShape) Draw() {fmt.Printf("设置颜色: %s\n", c.color)c.shape.Draw()
}

2. 动态切换实现

// 运行时切换渲染引擎
rect := NewRectangle(winRenderer, 15, 25)
rect.Draw() // Windows渲染rect.renderer = linuxRenderer
rect.Draw() // Linux渲染

七、总结

桥接模式通过 分离抽象与实现 解决多维度扩展问题,特别适合以下场景:

  1. 多维度变化:独立管理不同维度的变化
  2. 跨平台开发:统一抽象接口,差异化实现
  3. 动态配置:运行时切换实现逻辑

在 Go 中实现时需注意 组合优于继承 的原则,通过接口定义清晰的抽象边界。当系统存在多个独立变化维度时,桥接模式能显著降低代码复杂度。

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

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

相关文章

低代码(Low Code)全解析:从概念到应用,从选择到价值

​在数字化浪潮席卷全球的当下,企业对软件开发的效率与灵活性愈发重视,低代码平台应运而生并迅速掀起技术热潮。 本文基于笔者 6 年的低代码实践经验,深入剖析低代码的诸多方面,涵盖其定义、发展历程、国内平台对比、开发流程、与…

函数重载讲解

虽然在初识C-CSDN博客中介绍过,但还是感觉要单发出来大概讲解下 什么是函数重载? 函数重载是指在同一个作用域内,函数名相同,但它们的 参数列表 不同。C 允许你根据函数的参数个数、类型或者顺序的不同来定义多个同名函数。编译…

14-H指数

给你一个整数数组 citations ,其中 citations[i] 表示研究者的第 i 篇论文被引用的次数。计算并返回该研究者的 h 指数。 根据维基百科上 h 指数的定义:h 代表“高引用次数” ,一名科研人员的 h 指数 是指他(她)至少发…

关于es6-module的语法

ES6(ECMAScript 2015)引入了模块化的概念,旨在使 JavaScript 更加模块化、可维护和可重用。ES6 模块允许我们在不同的文件中组织和管理代码,使得不同模块之间的依赖关系更加清晰。 1. 导出(Export) 1.1 命…

Chrome多开终极形态解锁!「窗口管理工具+IP隔离插件

Web3项目多开,继ads指纹浏览器钱包被盗后,更多人采用原生chrome浏览器,当然对于新手,指纹浏览器每月成本也是一笔不小开支,今天逛Github发现了这样一个解决方案,作者开发了窗口管理工具IP隔离插件&#xff…

DeepSeek核心算法解析:如何打造比肩ChatGPT的国产大模型

注:此文章内容均节选自充电了么创始人,CEO兼CTO陈敬雷老师的新书《自然语言处理原理与实战》(人工智能科学与技术丛书)【陈敬雷编著】【清华大学出版社】 文章目录 DeepSeek大模型技术系列一DeepSeek核心算法解析:如何…

arm 入坑笔记

1.开发环境(IDE)使用keil_5 (keil_mdk) 2.两个手册需要关注:用户手册(编程需要),数据手册(硬件) 3.32bit地址空间:0~2^324GB寻址空间及(0-FFFF_FFFF&#x…

弱监督语义分割学习计划(0)-计划制定

经过与deepseek的一番讨论和交流,DeepSeek为我设计了一个30天高强度学习计划,重点聚焦弱监督/无监督语义分割在野外场景的应用,结合理论与实践,并最终导向可落地的开源项目。以下是详细计划: 总体策略 优先级排序&…

vscode远程报错:Remote host key has changed,...

重装了Ubuntu系统之后,由20.04改为22.04,再用vscode远程,就出现了以上报错。 亲测有效的办法 gedit ~/.ssh/known_hosts 打开这个配置文件 删掉与之匹配的那一行,不知道删哪一行的话,就打开第一行这个 /.ssh/confi…

Python - 爬虫利器 - BeautifulSoup4常用 API

文章目录 前言BeautifulSoup4 简介主要特点:安装方式: 常用 API1. 创建 BeautifulSoup 对象2. 查找标签find(): 返回匹配的第一个元素find_all(): 返回所有匹配的元素列表select_one() & select(): CSS 选择器 3. 访问标签内容text 属性: 获取标签内纯文本get_t…

DeepSeek驱动下的数据仓库范式转移:技术解耦、认知重构与治理演进

DeepSeek驱动下的数据仓库范式转移:技术解耦、认知重构与治理演进 ——基于多场景实证的架构革命研究 一、技术解耦:自动化编程范式的演进 1.1 语义驱动的ETL生成机制 在金融风控场景中,DeepSeek通过动态语法树解析(Dynamic Syn…

代码随想录算法训练营day38(补0206)

如果求组合数就是外层for循环遍历物品,内层for遍历背包。 如果求排列数就是外层for遍历背包,内层for循环遍历物品。 1.零钱兑换 题目 322. 零钱兑换 给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount &#xff0c…

golang channel底层实现?

底层数据实现 type hchan struct { qcount uint // 当前队列中的元素数量 dataqsiz uint // 环形队列的大小 buf unsafe.Pointer // 指向环形队列的指针 elemsize uint16 // 元素大小 closed uint32 // chan…

图的最小生成树算法: Prim算法和Kruskal算法(C++)

上一节我们学习了最短路径算法, 这一节来学习最小生成树. 最小生成树(Minimum Spanning Tree, MST)算法是图论中的一种重要算法, 主要用于在加权无向图中找到一棵生成树, 使得这棵树包含图中的所有顶点, 并且所有边的权重之和最小. 这样的树被称为最小生成树. 最小生成树广泛应…

矩阵系统源码搭建的数据管理开发功能解析,支持OEM

一、引言 在矩阵系统中,数据犹如血液,贯穿整个系统的运行。高效的数据管理开发功能是确保矩阵系统稳定、可靠运行的关键,它涵盖了数据的存储、处理、安全等多个方面。本文将深入探讨矩阵系统源码搭建过程中数据管理功能的开发要点。 二、数据…

DeepSeek 助力 Vue 开发:打造丝滑的日期选择器(Date Picker),未使用第三方插件

前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 Deep…

操作系统知识点2

1.P,V操作可以实现进程同步,进程互斥,进程的前驱关系 2.先来先服务调度算法是不可抢占的算法 3.UNIX操作系统中,对文件系统中空闲区的管理通常采用成组链接法 4.对于FAT32文件系统,它采用的是链接结构 5.不同的I/O…

【个人开发】deepspeed+Llama-factory 本地数据多卡Lora微调【完整教程】

文章目录 1.背景2.微调方式2.1 关键环境版本信息2.2 步骤2.2.1 下载llama-factory2.2.2 准备数据集2.2.3 微调模式2.2.3.1 zero-1微调2.2.3.2 zero-2微调2.2.3.3 zero-3微调2.2.3.4 单卡Lora微调 2.2.4 实验2.2.4.1 实验1:多GPU微调-zero12.2.4.2 实验2:…

iOS 中使用 FFmpeg 进行音视频处理

在 iOS 中使用 FFmpeg 进行音视频处理,通常需要将 FFmpeg 的功能集成到项目中。由于 FFmpeg 是一个 C 库,直接在 iOS 中使用需要进行一些配置和封装。 1. 在 iOS 项目中集成 FFmpeg 方法 1:使用 FFmpeg 预编译库 下载 FFmpeg iOS 预编译库: 可以从以下项目中获取预编译的 …

Elasticsearch:将 Ollama 与推理 API 结合使用

作者:来自 Elastic Jeffrey Rengifo Ollama API 与 OpenAI API 兼容,因此将 Ollama 与 Elasticsearch 集成非常容易。 在本文中,我们将学习如何使用 Ollama 将本地模型连接到 Elasticsearch 推理模型,然后使用 Playground 向文档提…