桥接模式:**将抽象和其实现分离,具体的子类使用不同的方式去实现,从而可以独立的改变它们。体现了组合重用原则。实现独立出来各自变化,每次变化不会影响其他实现 **。
桥接模式 Bridge
通俗的解释:实现系统可能有多角度的分类,每一种分类都有可能变化,那么就把这种多角度分离出来让他们独立变化,减少他们之间的耦合。任何多维度变化类或者多个树状类,都可以通过桥接模式解耦。
桥接模式的桥梁作用也是连接“抽象部分”和“实现部分”;或者是将不同角度的分类连接起来。
类图结构
结构解析
Abstraction
抽象类,定义了抽象接口,该类持有 Implement
对象的引用。
RefinedAbstraction
抽象类的具体实现,同时会对抽象方法进行完善和扩展。
Implementor
抽象类,实现部分的抽象类。实现 Abstraction
中的抽象方法。
ConcreteImplementor
实现部分的具体实现类。
示例
标准示例
按照标准类图结构实现的桥接模式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| public abstract class Implementor { public abstract void operationImpl(); }
public class ConcreteImplementor extends Implementor{ @Override public void operationImpl() { System.out.println("ConcreteImplementor::operationImpl"); } }
public abstract class Abstraction { protected Implementor implementor;
public Abstraction(Implementor implementor){ this.implementor = implementor; }
public abstract void operation(); }
public class RefinedAbstraction extends Abstraction{
public RefinedAbstraction(Implementor implementor) { super(implementor); }
@Override public void operation() { implementor.operationImpl(); System.out.println("RefinedAbstraction::operation::Extends!"); } }
public class TestStandardBridge { public static void main(String[] args) { Implementor implementor = new ConcreteImplementor(); Abstraction abstraction = new RefinedAbstraction(implementor); abstraction.operation(); } }
ConcreteImplementor::operationImpl RefinedAbstraction::operation::Extends!
|
咖啡
咖啡可以有多种分类方式,比如大杯小杯,有糖无糖等等,典型的多角度分类,可以桥接模式来实现客户拿到的咖啡。
这种分类方式还有:不同形状涂不同颜色的图形;不同系统使用不同通讯录,短信等软件的手机;不同操作系统播放不同格式视频的播放器等等,这些都可以使用桥接模式来实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| public abstract class Flavour { public abstract void addFlavor(); }
public class Sugar extends Flavour { @Override public void addFlavor() { System.out.println("Sugar"); } }
public class SugarFree extends Flavour{ @Override public void addFlavor() { System.out.println("SugarFree"); } }
public abstract class Coffee { protected Flavour flavour;
public Coffee(Flavour flavour){ this.flavour = flavour; }
public abstract void makeCoffee(); }
public class LargeCoffee extends Coffee { public LargeCoffee(Flavour flavour) { super(flavour); }
@Override public void makeCoffee() { System.out.printf("Large Cup Coffee "); flavour.addFlavor(); } }
public class SmallCoffee extends Coffee{ public SmallCoffee(Flavour flavour) { super(flavour); }
@Override public void makeCoffee() { System.out.printf("Small Cup Coffee "); flavour.addFlavor(); } }
public class TestCoffee { public static void main(String[] args) { Flavour flavour1 = new Sugar(); Flavour flavour2 = new SugarFree(); Coffee coffeeA = new LargeCoffee(flavour1); Coffee coffeeB = new SmallCoffee(flavour2);
coffeeA.makeCoffee(); coffeeB.makeCoffee(); } }
Large Cup Coffee Sugar Small Cup Coffee SugarFree
|
总结
- 优点
分离抽象接口及其实现部分,提高了系统的可扩充性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统。
- 缺点
桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。
桥接模式最大的特点是将抽象部分与它的实现部分分离,使它们都可以独立地变化,也就是两种维度可以独自扩展。
参考文档
- 大话设计模式
Android
源码设计模式解析与实战
- 桥接模式