介绍
对于这个模式有两种不同的理解方式。在 GoF 的《设计模式》一书中,桥接模式被定义为:“将抽象和实现解耦,让它们可以独立变化。”在其他资料和书籍中,还有另外一种更加简单的理解方式:“一个类存在两个(或多个)独立变化的维度,我们通过组合的方式,让这两个(或多个)维度可以独立进行扩展。”
对于第一种 GoF 的理解方式,弄懂定义中“抽象”和“实现”两个概念,是理解它的关键。定义中的“抽象”,指的并非“抽象类”或“接口”,而是被抽象出来的一套“类库”,它只包含骨架代码,真正的业务逻辑需要委派给定义中的“实现”来完成。而定义中的“实现”,也并非“接口的实现类”,而是一套独立的“类库”。“抽象”和“实现”独立开发,通过对象之间的组合关系,组装在一起。
对于第二种理解方式,它非常类似我们之前讲过的“组合优于继承”设计原则,通过组合关系来替代继承关系,避免继承层次的指数级爆炸
代码实现
/// <summary>
/// 游戏中常见的例子:
///
// 角色使用不同的武器攻击敌人
// 角色有不同类型(如战士、法师)
// 武器也有不同类型(如剑、魔法杖)
// 角色和武器是独立变化的
/// </summary>
public class Bridge
{
static void Main()
{
IWeapon sword = new Sword();
IWeapon magicWand = new MagicWand();
Character character= new Warrior(magicWand);
character.Attack();
Character shoote= new Shooter(magicWand);
shoote.Attack();
}
}
public interface IWeapon
{
void Attack();
}
// 具体武器
public class Sword : IWeapon
{
public void Attack()
{
Console.WriteLine("用剑劈砍");
}
}
public class MagicWand : IWeapon
{
public void Attack()
{
Console.WriteLine("用魔法释放火球");
}
}
// 角色抽象类
public abstract class Character
{
protected IWeapon weapon;
public Character(IWeapon weapon)
{
this.weapon = weapon;
}
public abstract void Attack();
}
// 具体角色
public class Warrior : Character
{
public Warrior(IWeapon weapon) : base(weapon) {}
public override void Attack()
{
Console.WriteLine("战士 :");
weapon.Attack();
}
}
public class Shooter : Character
{
public Shooter(IWeapon weapon) : base(weapon) {}
public override void Attack()
{
Console.WriteLine("射手 :");
weapon.Attack();
}
}
问题 1:桥接模式是否要求“一方是抽象,一方是具体”?
✅ 回答:
桥接模式并不是说一方是抽象,另一方必须是具体。它的核心目的是:
“将抽象(Abstraction)与实现(Implementor)解耦,使两者可以独立扩展。”
🧠 分析你代码中的结构:
因此,这个结构完全符合桥接模式:
抽象部分:角色系统可以扩展出 Warrior、Shooter...
实现部分:武器系统可以扩展出 Sword、MagicWand...
它们通过组合(而不是继承)来解耦角色与武器的绑定关系。
👉 所以两边都有继承层次是正常且必要的,桥接的意思是:抽象层(角色)通过接口持有实现层(武器),解耦了两者的耦合。
❓问题 2:桥接模式将 x×y 的组合复杂度降为 x+y,在哪体现?
✅ 回答:
这正是桥接模式最大的价值:避免类爆炸。
📈 假如没有桥接,你可能需要写很多类:
比如你有:
3个角色类型:Warrior、Shooter、Mage
3种武器:Sword、MagicWand、Bow
🧨 不使用桥接的传统写法:
你可能需要组合出以下 9 个类:
WarriorWithSword
WarriorWithMagicWand
WarriorWithBow
ShooterWithSword
ShooterWithMagicWand
...
这就是 x × y = 3 × 3 = 9 个类。
✅ 使用桥接模式之后:
你只需要维护:
3个角色子类(
Warrior
,Shooter
,Mage
)3个武器子类(
Sword
,MagicWand
,Bow
)
角色和武器可以 自由组合,你只需 x + y = 6 个类,在运行时组装即可:
Character shooter = new Shooter(new Bow());
Character mage = new Mage(new MagicWand());
这就是桥接模式“将类爆炸问题从乘法降到加法”的体现!