桥接模式在C#中通过组合+接口解耦实现,而非继承;适用于抽象与实现需独立变化的场景,如图形类型与渲染方式双维度扩展,新增类互不影响,避免子类爆炸。
桥接模式在 C# 中不是靠继承堆出来的,而是靠组合 + 接口解耦实现的;用错地方反而让代码更难懂,别一上来就套模板。
什么时候该用
而不是继承
当你发现类要同时沿着两个方向扩展——比如「图形类型(圆形、矩形)」和「渲染方式(矢量、光栅、WebGL)」——这时候每加一个图形 × 每加一种渲染,继承就会爆炸式增长。用桥接,新增图形只需写一个
子类,新增渲染只需写一个
实现,互不干扰。
抽象部分变化频繁(如支持新图形)
实现部分也常变(如适配新平台、新 API)
你已经在写类似
、
这种名字的类了 → 就是信号
运行时需要切换实现(比如用户点个按钮从光栅切到矢量)→ 桥接天然支持
类里为什么必须持有一个
接口引用
这是桥接的“桥”本身。没有这个引用,抽象就只能自己硬编码实现逻辑,又回到紧耦合。接口类型(比如
或
)保证了抽象层完全不知道具体实现细节。
C知道
CSDN推出的一款AI技术问答工具
下载
构造函数传入,不是 new 出来:避免抽象类依赖具体实现
字段声明为接口,不是具体类:
,不是
如果用了
在抽象类里,桥就断了,模式失效
推荐用
字段或
属性暴露给子类,但绝不 public set
和
怎么分工才不乱
(比如
)只负责「做什么」:描述图形语义(位置、半径)、调用
;
(比如
)只负责「怎么做」:真正调 OpenGL/WebGL API 画圆。
不写任何绘图代码,只做参数组装和委托调用
不知道 Circle 是啥,只接收字符串或结构体参数
如果
开始检查
做分支逻辑 → 桥接退化为条件判断,耦合回潮
参数尽量扁平(
或轻量
),避免把抽象层的数据模型强塞进实现层
容易被忽略的坑:生命周期与线程安全
桥接模式本身不解决资源管理问题。如果你的
持有 OpenGL 上下文或文件句柄,而
实例被反复复用、跨线程传递,就可能出错。
实现类如果是有状态的(如缓存着色器程序),需自行保证线程安全或明确文档标注「非线程安全」
不要让多个
共享同一个可变
实例,除非你确认它设计为可重入
常见反模式:
构造时 new 一个
,又没 Dispose 机制 → 内存泄漏或上下文丢失
建议:
实现
,由上层容器(如
)统一管理其生命周期,而非交给每个
BridgeShapeIRendererCircleWindowsRendererCircleLinuxRendererSetRenderer(new VectorRenderer())AbstractionImplementorIDrawingAPIIRendererprivate readonly IRenderer _renderer;VectorRenderernew VectorRenderer()protectedreadonlyRefinedAbstractionConcreteImplementorRefinedAbstractionCircle_renderer.Render("circle")ConcreteImplementorWebGLRendererCircle.Draw()WebGLRenderer.Render()Circle_renderer is WebGLRendererstring shapeNameShapeDataIRendererShapeIRendererShapeIRendererShapeRendererIRendererIDisposableRenderingEngineShape