模式开发之旅(11):桥接模式
2010-07-17 21:39:53桥接模式,也叫作桥梁模式,英文是 Bridge Design Pattern。这个模式可以说是 23 种设计模式中最难理解的模式之一了。
当然,这其中“最纯正”的理解方式,当属 GoF 的《设计模式》一书中对桥接模式的定义。毕竟,这 23 种经典的设计模式,最初就是由这本书总结出来的。在 GoF 的《设计模式》一书中,桥接模式是这么定义的:“Decouple an abstraction from its implementation so that the two can vary independently。”翻译成中文就是:“将抽象和实现解耦,让它们可以独立变化。”
关于桥接模式,很多书籍、资料中,还有另外一种理解方式:“一个类存在两个(或多个)独立变化的维度,我们通过组合的方式,让这两个(或多个)维度可以独立进行扩展。”通过组合关系来替代继承关系,避免继承层次的指数级爆炸。这种理解方式非常类似于“组合优于继承”设计原则。
桥接模式的应用举例
比如一款手机可以安装不同的应用,而手机又有多种不同的品牌。如果将手机按品牌分类,其结构图如下:
按软件分类实现结构图
由于实现的方式有多种,桥接模式的核心意图就是把这些实现独立出来,让它们各自地变化。这就使得每种实现的变化不会影响其他实现,从而达到应对变化的目的。
代码实现:
//手机软件
abstract class HandsetSoft
{
public abstract void Run();
}
//手机游戏
class HandsetGame : HandsetSoft
{
public override void Run()
{
Console.WriteLine("运行手机游戏");
}
}
//手机通讯录
class HandsetAddressList : HandsetSoft
{
public override void Run()
{
Console.WriteLine("运行手机通讯录");
}
}
//手机品牌
abstract class HandsetBrand
{
protected HandsetSoft soft;
//设置手机软件
public void SetHandsetSoft(HandsetSoft soft) //品牌需要关注软件,所以可以机器中安装软件,以备运行
{
this.soft = soft;
}
public abstract void Run();
}
//手机品牌N
class HandsetBrandN : HandsetBrand
{
public override void Run()
{
soft.Run();
}
}
//手机品牌M
class HandsetBrandM : HandsetBrand
{
public override void Run()
{
soft.Run();
}
}
//客户端调用代码
static void Main(string[] args)
{
HandsetBrand ab;
ab = new HandsetBrandN();
ab.SetHandsetSoft(new HandsetGame());
ab.Run();
ab.SetHandsetSoft(new HandsetAddressList());
ab.Run();
ab = new HandsetBrandM();
ab.SetHandsetSoft(new HandsetGame());
ab.Run();
ab.SetHandsetSoft(new HandsetAddressList());
ab.Run();
Console.Read();
}
这时假如我们需要增加一个功能,比如MP3音乐播放器,那么只增加这个类就可以了。不会影响其他任何类,类的个数也增加也只有一个。
//手机MP3播放
class HandsetMP3 : HandsetSoft
{
public override void Run()
{
Console.WriteLine("运行手机MP3播放");
}
}
如果是要增加S品牌,也只需要增加一个品牌子类就可以了。个数也是一个,不会影响其他类的改动。
//手机品牌S
class HandsetBrandS : HandsetBrand
{
public override void Run()
{
soft.Run();
}
}