桥模式,将意图intension与实现implementor分离。其中,意图通常用接口来定义,而实现相应为Factory,返回具体的意图Implemention1。
{
void Echo(string message);
}
public class Implemention1 : Intention
{
public void Echo(string message)
{
Console.WriteLine("Implemention1");
}
}
public class Factory
{
public static Intention Instantiate()
{
return new Implemention1();
}
}
意图Implemention1可以很容易的替换为另一个意图Implemention2。
这样,在Client端,我可以这样写:
Intention obj = Factory.Instantiate();
obj.Echo();
其中,被注释的行是我不希望使用的方式,指定具体对象的工作要交给工厂去做,这个工厂可以扩展为SimpleFactory,让用户决定生成什么样的对象。
我们还可以使用泛型接口,使得桥模式适用更通用的场合,比如说:
{
void Echo(T message);
}
以上是最基本的桥模式,但是现实中我们常常使用的是桥模式的变种,也就是在各个Blog/论坛/教科书上提及的,甚至连GOF的UML也是这么画的,
将意图intension与实现implementor分离,这句话太扯了,因为现实中根本分不清意图和实现,这往往是由我们自己定的,所以可以将定义改为:
如果系统可以沿着多个维度变化,那么可以将各个维度分离开,分别实现,从而最大程度的解耦。
——本质是:既然能抽象为乘法,就不要再使用加法。
举个例子说,一个水彩画系统,有7种颜料,同时呢,有大毛笔和小毛笔,那么我要设计14个类,分别是大毛笔的7种颜色类+小毛笔的7种颜色类——是没有问题的。如果新增加一个中毛笔,那么就要相应增加中毛笔的7种颜色类;如果增加一种颜料,那么就要相应增加大毛笔的1个颜色类+小毛笔的7个颜色类。这就有问题了——违背了类的单一职责原则,即一个类只有一个引起它变化的原因
我们称毛笔型号和颜料种类为水彩画系统的两个维度。该系统可以按照这两个维度变化,如果同时变化,那么类的数量会激增——这时候就要把毛笔型号和颜料种类分别抽象出来,这样的话,只有7种颜色类+2种毛笔型号类,当然,还要算上两个抽象基类。
Bridge与创建型模式的区别:
当一个系统只有一部分不稳定时,使用创建型模式;两部分或更多不稳定时,要使用Bridge来将其解耦,分别用Factory来实现。