Unity3DTraining 设计模式实战:桥接模式(Bridge Pattern)——把抽象与实现解耦,让课程与系所各自独立变化
示例工程【免费下载链接】Unity3DTraining【Unity杂货铺】unity大杂烩~项目地址https://gitcode.com/gh_mirrors/un/Unity3DTraining点击查看免费下载桥接模式Bridge Pattern是结构型设计模式中的经典一员它的核心是把抽象的部分与实现的部分分离让两者都能独立变化。本文以仓库 DesignPatterns/BridgePattern 目录下的 README 文档为主体结合其中完整的 C# 控制台示例源码讲解桥接模式的定义、适用场景、经典结构并给出可运行、可验证的选课系统改造代码。读完本文你将掌握桥接模式的判定方法、从继承爆炸到桥接解耦的重构思路以及 Abstraction / Implementor 两组层次在运行时如何自由组合。桥接模式的定义抽象与实现分离原文档给出了一个非常精炼的定义将抽象的部分与它的实现部分分离使他们都可以独立地变化。这里的实现指的是什么文档给出了关键注解实现指的就是抽象类和它的派生类用来实现自己的对象。换句话说抽象类本身并不直接完成全部工作而是把部分甚至全部职责委托给另一个独立的对象去完成这个被委托的对象就是实现。为什么需要这种分离文档用一个非常生活化的场景来解释课程既可以按照课程类别来区分数学类、计算机类……也可以按照系所来区分计算机系、数学系……。当业务中存在多种分类维度、且每种分类都需要独立变化时就特别适合使用桥接模式。也就是说桥接模式要解决的核心问题不是某个类怎么实现而是多个维度同时变化时如何避免维度之间的耦合。问题背景多维分类导致的继承爆炸在没有桥接模式之前面对课程按类别分 × 按系所分这样的二维分类需求最直觉的做法是用继承层层派生。但这样会很快陷入类爆炸的泥潭每新增一个课程类别就要为每一个系所各写一个子类每新增一个系所又要为每一个课程类别各写一个子类类别数 × 系所数 子类总数增长是乘法级别的一旦课程类别的行为发生变化所有相关子类都要跟着改耦合度极高。文档明确指出当代码完成桥接改造之后无论是新加一门数学类的课程还是新加一个需要选课的系所都只需要新增一个子类即可新加课程只需新增一个Math的子类新加系所只需新增一个Departments的子类。这样不仅降低了工作量还解决了使用继承带来的高耦合性问题并且符合开闭原则Open-Closed Principle对扩展开放、对修改关闭。仓库实战选课系统的桥接改造DesignPatterns/BridgePattern 目录下的BridgePattern是一个 .NET Framework 4.5.2 的控制台工程见 BridgePattern.csprojOutputType为Exe、TargetFrameworkVersion为v4.5.2。工程里同时演示了两部分内容选课系统示例与经典桥接结构示例。第一组层次系所抽象DepartmentsDepartments.cs 定义了系所这一维度。抽象类Departments持有一个课程对象mathCourse通过SetCourse方法注入这正是桥的关键系所不关心课程具体是哪一个只关心它有Select()能力并声明了抽象的选课行为Select()/// summary /// 系所抽象类代码 /// /summary abstract class Departments { //系所包含的课程对象 protected Math mathCourse; /// summary /// 设置课程 /// /summary /// param namemath/param public void SetCourse(Math math) { this.mathCourse math; } /// summary /// 选择课程 /// /summary public abstract void Select(); } //具体的系所代码 /// summary /// 计算机系 /// /summary class Computer : Departments { public override void Select() { Console.WriteLine(计算机专业同学选课); mathCourse.Select(); } } class Mathematics : Departments { public override void Select() { Console.WriteLine(数学系的同学选课); mathCourse.Select(); } }注意这里的委托关系Computer.Select()和Mathematics.Select()都只负责输出谁在选课然后把真正的选课动作转发给mathCourse.Select()。系所自身不实现任何具体课程逻辑这正是抽象与实现分离的体现。第二组层次课程抽象MathMath.cs 定义了课程这一维度。抽象类Math声明抽象的Select()其下是各个具体课程//数学课程 abstract class Math { public abstract void Select(); } //数学课程的具体类代码: /// summary /// 数学分析 /// /summary class MathAnalysis : Math { public override void Select() { Console.WriteLine(选择了数学分析); } } class AdvanceMath : Math { public override void Select() { Console.WriteLine(选择了高等数学); } }至此两个分类维度被拆成了两棵独立的继承树Departments抽象→Computer/Mathematics具体系所Math抽象→MathAnalysis/AdvanceMath具体课程。它们之间唯一的连接点是Departments中的protected Math mathCourse字段通过SetCourse()在运行时注入——这个连接点就是文档所说的桥。运行入口与可验证输出Program.cs 演示了运行时如何自由组合两个维度static void Main(string[] args) { //举例 Departments dp; dp new Computer(); dp.SetCourse(new AdvanceMath()); dp.Select(); dp new Mathematics(); dp.SetCourse(new MathAnalysis()); dp.Select(); //桥接模式 Abstraction abstraction new RedefineAbstraction(); abstraction.SetImplementor(new ConcreteImplementorA()); abstraction.Operation(); abstraction.SetImplementor(new ConcreteImplementorB()); abstraction.Operation(); }依据源码逐行推演控制台输出依次为计算机专业同学选课 选择了高等数学 数学系的同学选课 选择了数学分析 A的具体操作 B的具体操作可以看到同一个系所Computer可以搭配不同的课程同一个课程也可以被不同系所选择。维度之间的组合是在运行时由调用方决定的而不是在编译期通过继承固定死的。新增一门课程如线性代数只需新增一个Math子类所有系所无需改动新增一个系所同理。这就是文档所说的独立变化。经典桥接结构Abstraction 与 Implementor除了选课示例仓库还提供了桥接模式的经典骨架也就是设计模式教材中最标准的四角色结构。Implementor实现部分的抽象Implementor.cs 定义实现部分的抽象接口及其两个具体实现abstract class Implementor { public abstract void Operation(); } class ConcreteImplementorA : Implementor { public override void Operation() { Console.WriteLine(A的具体操作); } } class ConcreteImplementorB : Implementor { public override void Operation() { Console.WriteLine(B的具体操作); } }Abstraction抽象部分的骨架Abstraction.cs 定义抽象部分的骨架。抽象类持有一个Implementor引用通过SetImplementor()注入然后由具体的抽象子类把Operation()转发给实现对象abstract class Abstraction { protected Implementor implementor; public void SetImplementor(Implementor implementor) { this.implementor implementor; } public abstract void Operation(); } class RedefineAbstraction : Abstraction { public override void Operation() { implementor.Operation(); } }RedefineAbstraction是精化抽象Refined Abstraction它不关心implementor具体是 A 还是 B只负责把调用转发下去。这样Abstraction这一维与Implementor这一维就彻底解耦了任何一维扩展出新子类都不影响另一维。与选课示例的对应关系把经典结构套回选课场景对应关系一目了然经典角色选课示例Abstraction抽象Departments系所RefinedAbstraction精化抽象Computer/MathematicsImplementor实现接口Math课程ConcreteImplementor具体实现MathAnalysis/AdvanceMath桥BridgeDepartments.mathCourse字段 SetCourse()注入从这个对应表可以看出选课示例完全遵循了桥接模式的经典骨架只是换上了业务语义更强的类名。桥接模式的适用场景原文档给出了三条明确的适用判断标准这也是判断要不要用桥接模式的黄金准则当不希望在抽象和它的实现部分之间有一个固定的绑定关系时。桥接模式允许在运行时通过注入来改变绑定而不是在编译期用继承写死。当类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充时。两棵继承树各自独立扩展互不干扰。当对一个抽象类的实现部分的修改应对客户不产生影响时客户的代码不需要重新编译。因为客户只面向抽象接口编程实现细节被隔离在另一棵继承树中。文档还从抽象方法的视角给出了一个更深层的推导某个抽象是一个类那么它必依赖于抽象方法抽象的层次结构中父类的具体方法必然依赖于其他抽象方法。当我们沿着原层次结构按另一种方向继续派生子类时就不得不把这些抽象方法也一并移植到其他层级结构中去。此时就可以使用桥接模式——将一个抽象与这个抽象中所提供的抽象方法的实现互相分离。用更通俗的话说当你发现抽象层次结构和它依赖的抽象方法实现必须朝两个方向同时生长时把它们拆成两棵独立变化的树再用一个对象引用把两者桥接起来就是桥接模式的正确用法。小结桥接模式带来的独立变化文档的小结部分把桥接模式的效果总结得非常到位桥接模式从效果上解除了不同分类的实现之间的耦合性使其可以独立地变化。仍以选课代码为例课程与系所由于耦合性降低使得——增加课程时不会影响系所的代码新增Math子类即可Departments一族零改动增加系所时也不会影响课程的代码新增Departments子类即可Math一族零改动。这就是独立变化的确切含义也是开闭原则在结构层面的落地。相比继承带来的乘法级类数量桥接把复杂度从组合类数量降低为两个维度类数量的加法代价只是抽象接口上多一次运行时注入。从控制台示例到 Unity 游戏开发虽然本示例是一个脱离引擎的纯 C# 控制台工程但桥接模式在游戏开发中的价值同样直接。从行业实践看桥接模式常见于这些场景将渲染 API 抽象如 OpenGL / DirectX / Vulkan 的不同实现与具体渲染对象分离将输入设备差异与游戏逻辑层分离将不同平台的商店/支付 SDK与统一的业务接口分离。这些场景的共同特征与本例完全一致业务维度与平台/实现维度各自独立变化。仓库中的设计模式索引 DesignPatterns/README.md 将桥接模式与其他 23 种模式并列收录是 Unity3DTraining 项目Unity 杂货铺体系的一部分若想进一步了解游戏领域特有的模式可继续阅读 游戏编程模式。快速上手如何运行本示例使用 Visual Studio或 Rider / MonoDevelop打开 BridgePattern.csproj工程为 .NET Framework 4.5.2 控制台程序直接运行F5即可看到上述输出想验证独立变化的效果可以仿照现有代码新增一个Math子类例如线性代数并在Main中与Computer组合无需改动任何系所类即可编译运行。文中引用的全部源码均位于 BridgePattern 工程目录原始讲解文档为 BridgePattern/README.md读者可对照阅读逐行印证桥接模式从定义到落地的完整过程。赞分享示例工程【免费下载链接】Unity3DTraining【Unity杂货铺】unity大杂烩~项目地址https://gitcode.com/gh_mirrors/un/Unity3DTraining点击查看免费下载相关推荐CS-Notes 设计模式精讲桥接Bridge模式——把抽象与实现分开让两者独立演进CS Notes 设计模式精讲桥接Bridge模式——把抽象与实现分开让两者独立演进 本篇文章是 CS Notes 设计模式系列中「桥接Bridge知识库文档教程DyberPet桥接模式抽象与实现分离设计DyberPet桥接模式抽象与实现分离设计 在桌面宠物框架DyberPet中桥接模式Bridge Pattern作为核心设计思想实现了抽象层与实现层的桌面应用AI 应用交互助手别再只会用了Dear ImGui 即时模式 GUI 从原理到落地的快速上手别再只会用了Dear ImGui 即时模式 GUI 从原理到落地的快速上手 刚拿到 Dear ImGui 源码编译通过了可窗口一出来还是空白、中文字符UI组件前端桌面应用图形学上一篇Bytebase 任务运行日志上下文设计基于 slog 与 Context 的统一 Task Run 可观测性方案下一篇推荐开源项目OpenSSL-Universal - 完整的iOS与macOS OpenSSL解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

SqlMIResilientCloudApp 实战:用 C 重试逻辑打造可抵御 Azure SQL 托管实例故障转移的弹性云应用

SqlMIResilientCloudApp 实战:用 C 重试逻辑打造可抵御 Azure SQL 托管实例故障转移的弹性云应用

示例工程数据库教程后端 【免费下载链接】sql-server-samples Azure Data SQL Samples - Official Microsoft GitHub Repository containing code samples for SQL Server, Azure SQL, Azure Synapse, and Azure SQL Edge 项目地址: https://gitcode.com/gh_mirrors…

2026/9/25 2:14:59 阅读更多 →
基于特征线法MOC的水锤压力流量曲线计算:ZIELKE1基准算例复现与避坑指南

基于特征线法MOC的水锤压力流量曲线计算:ZIELKE1基准算例复现与避坑指南

简介:一套基于特征线法(MOC)实现动态摩阻管道流动求解的仿真资源,面向计算流体力学初学者、管道瞬变流分析人员及开展数值仿真课程设计的工科学生。资源围绕一维非稳态管道流动问题,重点演示如何在特征线上离散连续性与…

2026/9/25 2:14:59 阅读更多 →
eslint-plugin-react 的 react/jsx-first-prop-new-line 规则详解:统一 JSX 首个属性的换行位置

eslint-plugin-react 的 react/jsx-first-prop-new-line 规则详解:统一 JSX 首个属性的换行位置

开发工具代码质量静态分析 【免费下载链接】eslint-plugin-react React-specific linting rules for ESLint 项目地址: https://gitcode.com/gh_mirrors/es/eslint-plugin-react 点击查看 免费下载 本篇技术指南围绕 eslint-plugin-react 中的 react/jsx-first-pro…

2026/9/25 2:14:59 阅读更多 →

最新新闻

Apache DataFusion 中的 Arrow 入门:RecordBatch、ArrayRef 与列式执行原理详解

Apache DataFusion 中的 Arrow 入门:RecordBatch、ArrayRef 与列式执行原理详解

大数据数据分析后端 【免费下载链接】datafusion Apache DataFusion SQL Query Engine 项目地址: https://gitcode.com/gh_mirrors/datafu/datafusion 点击查看 免费下载 导读 Apache DataFusion 将 Apache Arrow 作为其原生内存数据格式,因此任何使用…

2026/9/25 2:50:25 阅读更多 →
Artillery 自定义插件开发实战:以 artillery-plugin-hello-world 为例剖析插件接口与扩展机制

Artillery 自定义插件开发实战:以 artillery-plugin-hello-world 为例剖析插件接口与扩展机制

性能测试接口测试CLI 【免费下载链接】artillery The complete load testing platform. Everything you need for production-grade load tests. Serverless & distributed. Load test with Playwright. Load test HTTP APIs, GraphQL, WebSocket, and more. Use any Node.…

2026/9/25 2:50:25 阅读更多 →
react-map-gl 入门指南:为 Mapbox GL JS 与 MapLibre GL JS 打造的 React 组件套件

react-map-gl 入门指南:为 Mapbox GL JS 与 MapLibre GL JS 打造的 React 组件套件

前端UI组件 【免费下载链接】react-map-gl React friendly API wrapper around MapboxGL JS 项目地址: https://gitcode.com/gh_mirrors/re/react-map-gl 点击查看 免费下载 react-map-gl 是一套专为 React 设计的开源组件库,它把 mapbox-gl 与 maplibr…

2026/9/25 2:50:25 阅读更多 →
Spyder 内置教程全解:从运行首个 Python 程序到调试、绘图与代码规范实战

Spyder 内置教程全解:从运行首个 Python 程序到调试、绘图与代码规范实战

开发工具IDE代码编辑器 【免费下载链接】spyder Official repository for Spyder - The Scientific Python Development Environment 项目地址: https://gitcode.com/gh_mirrors/sp/spyder 点击查看 免费下载 Spyder(Scientific Python Development Env…

2026/9/25 2:50:25 阅读更多 →
RocketRide llm_perplexity 节点深度解析:把 Perplexity Sonar 搜索增强大模型接入 AI 流水线

RocketRide llm_perplexity 节点深度解析:把 Perplexity Sonar 搜索增强大模型接入 AI 流水线

【免费下载链接】rocketride-server High-performance AI pipeline engine with a C core and 50 Python-extensible nodes. Build, debug, and scale LLM workflows with 13 model providers, 8 vector databases, and agent orchestration, all from your IDE. Includes VS C…

2026/9/25 2:50:25 阅读更多 →
ctf-wiki 橢圓曲線加密(ECC)從入門到實戰:離散對數基礎、ElGamal 方案與 SECCON CTF 破解

ctf-wiki 橢圓曲線加密(ECC)從入門到實戰:離散對數基礎、ElGamal 方案與 SECCON CTF 破解

文档网络安全教程 【免费下载链接】ctf-wiki Come and join us, we need you! 项目地址: https://gitcode.com/gh_mirrors/ct/ctf-wiki 点击查看 免费下载 本篇技術指南以 ctf-wiki 的 ecc.md 為主體,系統梳理橢圓曲線加密(Elliptic Curve C…

2026/9/25 2:49:25 阅读更多 →

日新闻

AI元人文:从工具使用到思维重构的深度探索

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:00:41 阅读更多 →
Python+CNN车牌识别实战:从数据预处理到模型训练与部署

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:00:41 阅读更多 →
Vim基础操作全攻略:保存退出、模式切换与高频命令实战

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/25 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/24 9:10:42 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →