首页/新闻资讯/正文详情

Unity3DTraining 设计模式实战:桥接模式(Bridge Pattern)——把抽象与实现解耦,让课程与系所各自独立变化

发布时间:2026/9/25 2:14:53 来源:云帆数科 栏目:资讯中心
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:53

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

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

Conventional Commits 1.0.0 规范全解读:从提交信息格式到自动化语义化版本
Conventional Commits 1.0.0 规范全解读:从提交信息格式到自动化语义化版本

文档 【免费下载链接】conventionalcommits.org The conventional commits specification 项目地址: https://gitcode.com/gh_mirrors/co/conventionalcommits.org 点击查看 免费下载 本文基于本仓库中 约定式提交规范 v1.0.0 的乌克兰语版本(content/v… · 2026/9/25 2:14:47

Angular + Apollo 实战:在 HowToGraphQL Hackernews 中实现 Limit-Offset 分页
Angular + Apollo 实战:在 HowToGraphQL Hackernews 中实现 Limit-Offset 分页

【免费下载链接】howtographql The Fullstack Tutorial for GraphQL 项目地址: https://gitcode.com/gh_mirrors/ho/howtographql 点击查看 免费下载 本篇以 HowToGraphQL 教程中 Angular Apollo 克隆 Hacker News 项目的分页章节为主线,讲解如何基于 … · 2026/9/25 2:43:43

Senparc.Weixin.MP 微信公众号 SDK 安装指南:源码引用与 NuGet 包两种方式详解
Senparc.Weixin.MP 微信公众号 SDK 安装指南:源码引用与 NuGet 包两种方式详解

后端即时通讯金融科技 【免费下载链接】WeiXinMPSDK 微信全平台 .NET SDK, Senparc.Weixin for C#,支持 .NET Framework 及 .NET Core、.NET 10.0。已支持微信公众号、小程序、小游戏、微信支付、企业微信/企业号、开放平台、JSSDK、微信周边等全平台。 … · 2026/9/25 2:43:43

猫抓 cat-catch 使用指南:如何从网页中嗅探并下载视频与 M3U8 流
猫抓 cat-catch 使用指南:如何从网页中嗅探并下载视频与 M3U8 流

猫抓 cat-catch 使用指南:如何从网页中嗅探并下载视频与 M3U8 流 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 你在网页上看到一个想… · 2026/9/25 2:43:43

html-anything 像素动画技能实战:用纯 CSS 打造 8-bit 复古解说帧
html-anything 像素动画技能实战:用纯 CSS 打造 8-bit 复古解说帧

AI 应用人工智能AI AgentAI 写作媒体生成 【免费下载链接】html-anything ✨ The agentic HTML editor — your local AI agent writes the HTML, you ship it. 🚀 75 Skills 9 Surfaces (magazine deck poster XHS / tweet prototype data report Hyperfram… · 2026/9/25 2:43:43

Keil5 彻底卸载指南:注册表清理与隐藏残留全攻略
Keil5 彻底卸载指南:注册表清理与隐藏残留全攻略

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 2:43:43

Kali Linux无线渗透测试实战:从握手包捕获到WPA/WPA2离线破解
Kali Linux无线渗透测试实战:从握手包捕获到WPA/WPA2离线破解

很多人把 Kali Linux 当成“黑客系统”的代名词,其实它更像一把功能齐全的瑞士军刀,尤其是在无线网络渗透测试这个细分领域里,Kali 几乎就是默认主场。无线网络、WPA/WPA2 加密、握手包、字典攻击这些词,玩过安全测试的人都不陌生… · 2026/9/25 2:43:36

数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)
数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码