跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

C#怎么实现桥接模式_C#设计模式之Bridge Pattern教程【进阶】

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

相关文章