Bridge桥连接模式的作用是将两样东西链接起来,它们分别是类的功能层次结构和类的实现层次结构。
类的功能层次结构
当有一个Something类,要增加它的功能时,可以创建SomethingGood类同时继承Something类,这样就构成了一个小的类的层次结构。
父类具有基础的功能
在子类中增加新的功能
以上就称为类的功能层次结构。注意类的功能层次结构不应该太深。
类的实现层次结构
抽象类声明了一些抽象方法,定了了API接口,然后子类负责实现这些抽象方法。父类的任务是通过抽象方法的方式定义接口,而子类的任务是实现抽象方法。这里其实存在层次结构。例如子类ConcreteClass实现了父类AbstractClass类的抽象方法,它们之间就构成了一个小的层次结构。
父类通过声明抽象方法来定义接口API
子类通过实现具体方法来实现接口API
这种层次结构称为“类的实现层次结构”。
当我们编写子类时,我们要确认是要增加新功能还是增加实现。当类的层次结构只有一层时,功能层次结构与实现层次结构是混合在一起的,这样很容易使类的层次结构变得复杂,也难理解类的层次结构。
因此我们需要将类的功能层次结构和类的实现层次结构分开。再使用Bridge模式将两种层次结构关联起来。
角色:
Abstraction抽象化:该角色位于 “类的功能层次结构”的最上层。它使用Implementor角色的方法定义了基本的功能。该角色中保存了Implementor角色的实例。
RefinedAbstraction改善后的抽象化:在Abstraction角色基础上增加了新的功能。
Implementor实现者:该角色位于“类的实现层次结构”的最上层,它定义用于实现Abstraction角色的接口API。
ConcreteImplementor具体实现者:该角色实现了Implementor角色中定义的接口API。
重点说明:
类的功能层次结构是通过继承来体现的,子类继承父类后可以增加新的功能。
类的实现层次结构是通过抽象类和实现类来体现的,实现了继承了抽象类并且实现了抽象类中的抽象方法。
继承是强关系,委托是弱关系。
Bridge模式通过委托方式把“类的实现层次结构”委托给“类的功能层次结构”,在代码中体现为:Display父类通过委托方式调用DisplayImpl抽象类。
代码:
public abstract class DisplayImpl { public abstract void rawOpen(); public abstract void rawPrint(); public abstract void rawClose(); }
public class StringDisplayImpl extends DisplayImpl { private int width; private String string; public StringDisplayImpl(String string) { this.string = string; this.width = string.length(); } @Override public void rawOpen() { pringLine(); } @Override public void rawPrint() { System.out.println("|" + string + "|"); } @Override public void rawClose() { pringLine(); } private void pringLine() { System.out.print("+"); for(int i=0;i<width;i++) { System.out.print("-"); } System.out.println("+"); } }
public class Display { private DisplayImpl impl; public Display(DisplayImpl impl) { this.impl = impl; } public void open() { impl.rawOpen(); } public void print() { impl.rawPrint(); } public void close() { impl.rawClose(); } public final void display() { open(); print(); close(); } }
public class CountDisplay extends Display { public CountDisplay(DisplayImpl impl) { super(impl); } public void multiDisplay(int times) { open(); for(int i=0;i<times;i++) { print(); } close(); } }
public class Main { public static void main(String[] args) { Display display1 = new CountDisplay(new StringDisplayImpl("display1")); Display display2 = new CountDisplay(new StringDisplayImpl("display2")); CountDisplay display3 = new CountDisplay(new StringDisplayImpl("display2")); display1.display(); display2.display(); display3.display(); display3.multiDisplay(3); } }
结果:
+--------+
|display1|
+--------+
+--------+
|display2|
+--------+
+--------+
|display2|
+--------+
+--------+
|display2|
|display2|
|display2|
+--------+