桥接器模式(BridgePattern)又称为桥梁模式,它主要用意是为了实现抽象部分与实现部分脱耦,使它们各自可以独立地变化。
在开发过程中大家通常会遇到一个对象有两个变化的维度,而且这两个维度变化地非常巨烈,这种变化导致了纵横交错的结果,使对象的设计变得困难,并且在对象数量上和可扩展性上都带来了很大的麻烦。此时我们应当把这两个变化比较巨烈的维度拆离,然后用组合的方式把它们结合在一起。这就是桥接器模式的思想。
生活中的例子:
1、开关与台灯:任何台灯都包括灯泡和灯架两部分,不同的灯泡可以与不同的台灯(灯架)匹配,可以只更换灯泡或只更换台灯(灯架),灯泡与台灯(灯架)之间存在一种交错的巨烈变化,所以把灯和台灯“做死”在一起不是一种好的作法。可以使用桥接器模式使之解耦:在台灯(灯架)上做一个灯口,可以用它来调用灯泡的“发光”的方法点亮灯泡,同时我们可以随意地更换我们喜欢的灯泡,而不用去换整个台灯(灯架)。
2、蜡笔与毛笔:(参见吕震宇老师的例子http://www.cnblogs.com/zhenyulu/articles/67016.html)
结构图:
![](http://hiphotos.baidu.com/grayworm/pic/item/f5f3432374ccab439358072a.jpg)
示例代码:
//抽象化角色
abstract class Abstraction
{
private Implementor imp; //抽象部分包含的实现者
public Implementor Imp
{
set
{
imp = value;
}
get
{
return imp;
}
}
public abstract void Operation();
}
//派生抽象化角色
class RefinedAbstraction : Abstraction
{
public override void Operation()
{
Imp.OperationImp(); //调用实现者的方法实现操作
}
}
//实现者角色
abstract class Implementor
{
public abstract void OperationImp();
}
//具体实现者角色A
class ConcreteImplementorA : Implementor
{
public override void OperationImp()
{
Console.WriteLine("ConcreteImplementA's Operator !");
}
}
//具体实现者角色B
class ConcreteImplementorB : Implementor
{
public override void OperationImp()
{
Console.WriteLine("ConcreteImplementB's Operator !");
}
}
class Class2
{
public static void Main(string[] args)
{
Abstraction a = new RefinedAbstraction();
a.Imp = new ConcreteImplementorA();
a.Operation();
a.Imp = new ConcreteImplementorB();
a.Operation();
}
}
举例:台灯与灯泡
为了实现灯架与灯泡之间的解耦,我们使用桥接器模式,抽象出一个“抽象化台灯”,它有一个开关一个灯泡,可以通过开关调用灯泡的发光方法来实现发光。同时我们也为灯泡做了一个抽象,以使此灯的灯泡可以恰好安装在灯架的灯口上。
下面为抽象出来的灯架和灯泡派生两个灯泡和两个灯架:
两个台灯的灯架:一个是旋钮式开关,另一个是按钮式开关。
两个灯泡:红色灯泡和蓝色灯泡。
代码:
//抽象台灯
abstract class Lamp
{
protected Light light; //台灯上的灯泡
public Light Light
{
set
{
light = value;
}
}
public abstract void OpenLight(); //台灯的开关
}
//旋钮台灯
class CircleLamp: Lamp
{
private int v=0; //旋钮台灯打开后,灯泡的最初电压
public override void OpenLight() //旋转台灯开关调亮灯泡
{
for (v = 0; v <= 5; v++)
{
light.Level = v; //根据电压设定灯泡发光强度
light.Shine(); //灯泡发光
}
}
}
//按钮台灯
class SwitchLamp : Lamp
{
private int v = 5; //打开台灯开关后,灯泡的最初电压
public override void OpenLight() //打开按钮台灯的开关
{
light.Level = v; //根据电压设定灯泡发光强度
light.Shine();//灯泡发光
}
}
//灯泡抽象体
abstract class Light
{
protected int level; //灯泡的发光强度
public int Level
{
set
{
level = value;
}
}
public abstract void Shine(); //灯泡的发光方法
}
//红灯
class RedLight:Light
{
public override void Shine()
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < level; i++)
{
sb.Append("红");
}
Console.WriteLine(sb.ToString());
}
}
//蓝灯
class BlueLight:Light
{
public override void Shine()
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < level; i++)
{
sb.Append("蓝");
}
Console.WriteLine(sb.ToString());
}
}
class Client
{
public static void Main(string[] args)
{
Light l1 = new RedLight();
Light l2 = new BlueLight();
Console.WriteLine("======旋钮式台灯======");
Lamp lc1 = new CircleLamp();
lc1.Light = l1;
lc1.OpenLight();
lc1.Light = l2;
lc1.OpenLight();
Console.WriteLine("\n======按钮式台灯======");
Lamp lc2 = new SwitchLamp();
lc2.Light = l1;
lc2.OpenLight();
lc2.Light = l2;
lc2.OpenLight();
Console.WriteLine("\n");
}
}
![](http://hiphotos.baidu.com/grayworm/pic/item/c5964055b18516c9b645ae36.jpg)
适用情况:
在以下的情况下应当使用桥梁模式:
1.如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的联系。
2.设计要求实现化角色的任何改变不应当影响客户端,或者说实现化角色的改变对客户端是完全透明的。
3.一个构件有多于一个的抽象化角色和实现化角色,系统需要它们之间进行动态耦合。
4.虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计要求需要独立管理这两者。
Bridge模式是一个非常有用的模式,也非常复杂,它很好的符合了开放-封闭原则和优先使用对象,而不是继承这两个面向对象原则
转:http://hi.baidu.com/grayworm/blog/item/883c493b1436c2ee14cecb4b.html