1. 简介
桥接模式,引用百度百科的解释如下:
桥接模式是将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interfce)模式。
由上可以看出来,它存在两个维度的对象:抽象部分和实现部分。那么什么是抽象部分,什么是实现部分呢。
实现部分:一般的,它存在于抽象部分,继承于统一个接口的实例。
抽象部分:对实现部分的接口方法进行具体逻辑使用,以达到需求的最终目的,它是对实现的具体抽象和包装。
以上,解释的有点抽象,下面会以具体场景进行说明。例如:一家饮品店,有多种饮品,饮品又分为大杯、中杯、小杯。那么从这个场景中,我们会发现:饮品的种类是会发生变化的,那么杯子的型号发生变化吗?答案是会的,为了一些营销策略,老板可能去掉了小杯的型号,改为:中杯、大杯、特大杯。(是不是想到了罗永浩再星巴克抽自己脸的小短片了?)。那么,这两个模块都可以独自的变化,彼此又有一种联系:杯子里需要装饮品。如果不使用桥接模式的化,单单是继承的方式构建类,那么会出现m*n个类的情况,且每增加一种类型,类的个数会成倍的增加。所以这里可否让其各自变化,将包装饮品的抽象化与做饮品的实现化进行分离,这样就只会有m+n个类,而我们只需要通过一个类似桥的方式将两者联系起来,使的实现部分实现客户的具体需求。
2. 类图
3. 代码实列
如下,根据简介中的场景,我们有一个饮品的实现接口类和一个抽象的杯子类,同时两个实体各自发展变化:
实现部分
interface IDrink {
public void doDrink();
}
class ECoffe implements IDrink {
@Override
public void doDrink() {
//do coffe ...
System.out.print("Coffee is done!");
}
}
class EFruitTea implements IDrink {
@Override
public void doDrink() {
// do fruit tea
System.out.print("fruit is done!");
}
}
class EMilk implements IDrink {
@Override
public void doDrink() {
// do milk
System.out.print("milk is done!");
}
}
抽象部分
abstract class ECup {
protected IDrink drink;
public void setDrink(IDrink drink) {
this.drink = drink;
}
public abstract void doWrap();
}
class ESmallCup extends ECup {
@Override
public void doWrap() {
// small cup
this.drink.doDrink();
System.out.println(" Packing a small cup...");
}
}
class EMediumCup extends ECup {
@Override
public void doWrap() {
// small cup
this.drink.doDrink();
System.out.println(" Packing a medium cup...");
}
}
class EBigCup extends ECup {
@Override
public void doWrap() {
// small cup
this.drink.doDrink();
System.out.println(" Packing a big cup...");
}
}
客户代码
public static void main(String[] args) {
ECup smallCup = new ESmallCup();
IDrink coffe = new ECoffe();
smallCup.setDrink(coffe);
smallCup.doWrap();
ECup bigCup = new EBigCup();
IDrink milk = new EMilk();
bigCup.setDrink(milk);
bigCup.doWrap();
}
输出
Coffee is done! Packing a small cup…
milk is done! Packing a big cup…
总结
桥接模式的使用场景具有一定的局限性,具体表现在:
- 当一个类需要两个独立变化的维度,且两个维度会根据需求的变化进行扩展。
- 当一个场景下,类的扩展速度以m*n的方式进行的时候,为了减少类的膨胀,可以使用桥接模式,将其减少到m+n。
当然使用桥接模式在一定程度上减少了抽象部分和实现部分的耦合,减少了因为单一继承导致的系统的耦合性较高。同时,它也造成了系统的理解性的复杂。我们需要根据一定的场景进行合理和灵活使用,其中也包括它与其它模式的结合使用,如与适配器模式的结合,这里就不做过多的解释了。