Bridge 桥接模式简介与 C# 示例【结构型2】【设计模式来了_7】
〇、简介
1、什么是桥接模式?
一句话解释:
通过一个类的抽象,与另一个类的抽象关联起来,当做桥。此后不管两个抽象类的实现有多少种,均可以通过这个桥来将两个对象联系起来。
桥接,顾名思义就是用桥来连接河两岸,将原本不关联的两部分联系起来,且不影响两岸的各自演化,演化出来的不同对象仍可以通过这个桥连接。
桥接设计模式是一种结构型设计模式,它通过将抽象与其实现分离来实现松耦合。这种模式可以使得抽象和实现可以独立地进行扩展,而不会相互影响。
官方意图描述:将抽象部分与它的实现部分分离,使它们可以独立地变化。
一个比喻:(班主任为学生订餐)
学生和餐品相当于两个变化的类,均可以增加或减少,老师就相当于桥接模式中的桥。学生想吃什么套餐,可以通过老师来对应到具体的套餐类别。
2、优缺点和适用场景
- 分离抽象接口及其实现部分。桥接模式使用“对象间的关联关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。
- 在很多情况下,桥接模式可以取代多层继承方案,多层继承方案违背了“单一职责原则”,复用性较差,且类的个数非常多,桥接模式是比多层继承方案更好的解决方法,它极大减少了子类的个数。
- 桥接模式提高了系统的可扩展性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统,符合“开闭原则”。
- 桥接模式的使用会增加系统的理解与设计难度,由于关联关系建立在抽象层,要求开发者一开始就针对抽象层进行设计与编程。
- 桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性,如何正确识别两个独立维度也需要一定的经验积累。
适用场景:
- “抽象部分”和“实现部分”可以以继承的方式独立扩展而互不影响,在程序运行时可以动态将一个抽象化子类的对象和一个实现化子类的对象进行组合,即系统需要对抽象化角色和实现化角色进行动态耦合。
- 一个类存在两个(或多个)独立变化的维度,且这两个(或多个)维度都需要独立进行扩展。
- 不希望使用继承或因为多层继承导致系统类的个数急剧增加的系统。
实际适用场景:
- 游戏开发:在游戏开发中,可以使用桥接模式将游戏引擎和场景分离开来,使得用户可以在不同的场景之间进行切换,而不需要修改游戏引擎的代码。
- 网络编程:在网络编程中,可以使用桥接模式将协议和实现分离开来,使得用户可以在不同的协议之间进行切换,而不需要修改实现的代码。
- 图形界面开发:在图形界面开发中,可以使用桥接模式将控件的样式和布局分离开来,使得用户可以在不同的样式和布局之间进行切换,而不需要修改代码。
参考:https://zhuanlan.zhihu.com/p/58903776
一、代码示例
首先一起看下不使用桥接模式的示例。
假设我们正在开发一个图形绘制应用程序,需要支持不同类型的图形(例如圆形、正方形)以及不同类型的绘制方式(例如红色、蓝色)。在不使用桥接设计模式的情况下,我们可能会创建以下类层次结构:
// 图形基类
abstract class Shape
{
public abstract void Draw();
}
// 圆形
class Circle : Shape
{
public override void Draw()
{
Console.WriteLine("Drawing a circle");
}
}
// 正方形
class Square : Shape
{
public override void Draw()
{
Console.WriteLine("Drawing a square");
}
}
// 红色绘制器
class RedColor : Shape
{
public override void Draw()
{
Console.WriteLine("Drawing in red color");
}
}
// 蓝色绘制器
class BlueColor : Shape
{
public override void Draw()
{
Console.WriteLine("Drawing in blue color");
}
}
在上述代码中,我们有一个基类 Shape 和两个派生类 Circle 和 Square,分别表示圆形和正方形。另外,我们还有两个派生类 RedColor 和 BlueColor,分别表示红色和蓝色的绘制器。这种实现方式存在一个问题:当我们需要绘制不同颜色的图形时,必须在每个具体图形类中添加相应颜色的绘制方法。这导致了类层次结构的爆炸增长,使得代码难以维护和扩展。
使用桥接设计模式,我们可以将图形和颜色的实现分离开来。如下示例代码,我们定义一个新的抽象类 Color,表示颜色的实现,在 Shape 类中,将颜色的实现作为一个成员变量,并在 Draw 方法中调用颜色的 ApplyColor 方法:
class Program
{
static void Main(string[] args) // 测试一下
{
Color red = new Red();
Color blue = new Blue();
Shape redCircle = new Circle(red); // 通过将不同的颜色实例传递给图形类的构造函数来绘制不同颜色的图形
Shape blueSquare = new Square(blue);
redCircle.Draw();
blueSquare.Draw();
Console.ReadLine();
}
}
// 颜色基类
abstract class Color
{
public abstract void ApplyColor();
}
class Red : Color // 红色
{
public override void ApplyColor()
{
Console.WriteLine("Applying red color");
}
}
class Blue : Color // 蓝色
{
public override void ApplyColor()
{
Console.WriteLine("Applying blue color");
}
}
// 修改后的图形基类
abstract class Shape // (目标接口,定义了客户端期望的操作:Draw)
{
protected Color color; // 将颜色的实现作为一个成员变量
public Shape(Color color)
{
this.color = color;
}
public abstract void Draw();
}
class Circle : Shape // 圆形
{
public Circle(Color color) : base(color) // (被适配者 Color 的引用)
{ }
public override void Draw()
{
Console.Write("Drawing a circle. ");
color.ApplyColor(); // 在 Draw 方法中调用颜色的 ApplyColor 方法
}
}
class Square : Shape // 正方形
{
public Square(Color color) : base(color)
{ }
public override void Draw()
{
Console.Write("Drawing a square. ");
color.ApplyColor(); // 在 Draw 方法中调用颜色的 ApplyColor 方法
}
}

通过使用桥接设计模式,我们成功地将图形和颜色的实现解耦,使得它们可以独立地进行扩展。
如果后续需求增加,需要加一个颜色黄色,然后图形加一个椭圆,此时就可以分别再实现两个抽象类(Color、Shape)即可。
二、桥接模式的结构

Abstraction:定义抽象类的接口,维护一个指向 Implementor 类型对象的指针。
Implementor:定义实现类的接口,该接口不一定要与 Abstraction 的接口完全一致,事实上这两个接口可以完全不同。一般来讲,Implementor 接口仅提供进本操作,而 Abstraction 则定义了基于这些基本操作的较高层次的操作。
ConcreteInplementor:实现 Implementor 接口并定义它的具体实现。
三、相关模式
AbstractFactory 模式可以用来创建和配置一个特定的 Bridge 模式。
Adapter 模式用来帮助无关的类协同工作,它通常在系统设计完成后才会被使用。然而,Bridge 模式则是在系统开始时就被使用,它使得抽象接口和实现部分可以独立进行改变。
Bridge 桥接模式简介与 C# 示例【结构型2】【设计模式来了_7】的更多相关文章
- 设计模式07: Bridge 桥接模式(结构型模式)
Bridge 桥接模式(结构型模式) 抽象与实现 抽象不应该依赖于实现细节,实现细节应该依赖于抽象. 抽象B稳定,实现细节b变化 问题在于如果抽象B由于固有的原因,本身并不稳定,也有可能变化,怎么办? ...
- Bridge桥接模式(结构型模式)
现有一个需求,一个游戏系统需要构建不同风格的房屋,暂不考虑其他设计模式,需要能实现在PC端.移动端....等等多个平台的构建.最简单的实现方式如下: /// <summary> /// 房 ...
- Bridge 桥接模式 MD
桥接模式 简介 将抽象部分与实现部分分离,使它们都可以独立的变化. 业务抽象角色引用业务实现角色,或者说业务抽象角色的部分实现是由业务实现角色完成的 Bridge模式基于类的最小设计原则,通过使用封装 ...
- 一天一个设计模式——Bridge桥接模式
一.概念准备 在理解桥接模式之前,先要理解面向对象程序设计中的两个概念: 类的功能层次结构:假设现在有一个类Something,这个类有一些成员属性和成员方法,但是现有的功能不能满足要求,因此我们想扩 ...
- C++设计模式-Bridge桥接模式
作用:将抽象部份与它的实现部份分离,使它们都可以独立地变化. 将抽象(Abstraction)与实现(Implementation)分离,使得二者可以独立地变化. 桥接模式号称设计模式中最难理解的模式 ...
- Bridge桥接模式(设计模式11)
在没有使用桥接模式: 扩展新问题(类归属膨胀问题) 1增加性的电脑类型,要增加每个品牌下面的类 2如果要增加一个新的电脑品牌,要增加美中电脑类型的类 违背单一职责原则: · 一个类:联想笔记本,有两个 ...
- C#设计模式之十一外观模式(Facade)【结构型】
一.引言 快12点半了,要开始今天的写作了.很快,转眼设计模式已经写了十个了,今天我们要讲[结构型]设计模式的第五个模式,该模式是[外观模式],英文名称是:Facade Pattern.我们先从名字上 ...
- C#设计模式之十三代理模式(Proxy)【结构型】
一.引言 今天我们要讲[结构型]设计模式的第七个模式,也是"结构型"设计模式中的最后一个模式,该模式是[代理模式],英文名称是:Proxy Pattern.还是老套路,先从名字 ...
- C#设计模式之十组合模式(Composite)【结构型】
一.引言 今天我们要讲[结构型]设计模式的第四个模式,该模式是[组合模式],英文名称是:Composite Pattern.当我们谈到这个模式的时候,有一个物件和这个模式很像,也符合这个模式要表达 ...
- C#设计模式之十二享元模式(Flyweight)【结构型】
一.引言 今天我们要讲[结构型]设计模式的第六个模式,该模式是[享元模式],英文名称是:Flyweight Pattern.还是老套路,先从名字上来看看."享元"是不是可以这样 ...
随机推荐
- MongoDB从入门到实战之.NET Core使用MongoDB开发ToDoList系统(8)-Ant Design Blazor前端框架搭建
前言 前面的章节我们介绍了一些值得推荐的Blazor UI组件库,通过该篇文章的组件库介绍最终我选用Ant Design Blazor这个UI框架作为ToDoList系统的前端框架.因为在之前的工作中 ...
- python学习--采集弹幕信息
# -*- coding: utf-8 -*-"""Created on Mon Nov 4 12:00:12 2019 @author: DELL"" ...
- Centos安装ELK
目录 安装Elastic Search 安装 Java 安装Elastic Search 修改配置 开放端口 访问地址 相关命令 安装elasticsearch-head插件 安装Git 安装node ...
- AcWing 4495. 数组操作题解
思路 此题较为简单,简述一下思路. 从小到大排序,每次选取最小值,只要不为0即可 每次都为序列减去一个数字太慢,但每个数又减去的数字一样,所以可以用minus记录每个数要减去的数 C++代码 #inc ...
- 大语言模型中一个调皮的EOS token
背景 最近需要做一个微调的培训,所以不可避免地需要上手一下相关的微调,而受限于机器资源,暂时没法做全参数微调,所以就尝试了目前比较火的两种高效微调方式,分别是PTuning和LoRA.模型选择得自然是 ...
- 与AI对话 -- 20230215 -- linux 启动参数与控制台
linux 启动参数 console=ttyS0,115200n8 console=tty0 说明 console=ttyS0,115200n8:指定系统使用 ttyS0(ttyS1.ttyS2 以此 ...
- 是时候丢掉BeanUtils了
前言 为了更好的进行开发和维护,我们都会对程序进行分层设计,例如常见的三层,四层,每层各司其职,相互配合.也随着分层,出现了VO,BO,PO,DTO,每层都会处理自己的数据对象,然后向上传递,这就避免 ...
- 手写 Vuex4 源码
本文首发于掘金,未经许可禁止转载 Vuex4 是 Vue 的状态管理工具,Vuex 和单纯的全局对象有以下两点不同: Vuex 的状态存储是响应式的 不能直接改变 store 中的状态.改变 stor ...
- 论文解读(IW-Fit)《Better Fine-Tuning via Instance Weighting for Text Classification》
Note:[ wechat:Y466551 | 可加勿骚扰,付费咨询 ] 论文信息 论文标题:Better Fine-Tuning via Instance Weighting for Text Cl ...
- P1830题解
思路: 利用桶存储轰炸区域,双重循环. 在存储轰炸区域时将次数刷新,也就是pos[j][k]=i;. 下面是核心代码: for(int i=1;i<=x;i++) { int x1,x2,y1, ...