Bridge桥接模式
Bridge的意思是“桥梁”。桥梁的作用是将河流的两侧连接起来。
Bridge模式的作用也是将两样东西连接起来,分别是类的功能层次结构和类的实现层次结构。
类的层次结构的两个作用
- 希望增加新功能时
假设现有一个类something。当我们想在Something中增加新功能时(想增加一个具体方法时),
会编写一个Something类的子类(派生类)。即SomethingGood类。这样就构成一个小小的类
层次结构。
Something
|___SomethingGood
这就是为了增加新功能而产生的层次结构。- 父类具有基本功能
- 在子类中增加新的功能
以上这种结构被称为“类的功能层次结构”。
- 希望增加新的实现时
抽象类声明了一些抽象方法,定义了接口(API),然后子类负责去实现这些抽象方法。父类的任务
是通过声明抽象方法定义接口,而子类的任务是实现抽象方法。正是父类和子类的这种任务分担,
才可以编写出具有高可替换性的类。
其中也有存在层次结构。例如当子类ConcreteClass实现了父类AbstractClass类的抽象方法时,它们
之间就构成了一个小小的层次结构。
AbstractClass
|___ConcreteClass
但是,这里的类的层次结构并非用于增加功能,也就是说,这种层次结构并非用于方便我们增加新的
方法。它的真正作用是帮助我们实现下面这样的任务分组。- 父类通过声明抽象方法来定义接口(API)
- 子类通过实现具体方法来实现接口(API)
这种层次结构被称为“类的实现层次结构”。
示例程序
在桥的哪一侧 | 名字 | 说明 |
---|---|---|
类的功能层次结构 | Display | 负责“显示”的类 |
类的功能层次结构 | CountDisplay | 增加了“只显示规定次数”这一功能的类 |
类的实现层次结构 | DisplayImpl | 负责“显示”的类 |
类的实现层次结构 | StringDisplayImpl | “用字符串显示”的类 |
Display类
package bridge;
/**
* @author wenei
* @date 2021-05-24 12:02
*/
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();
}
}
Display类的功能是抽象的,负责“显示一些东西”。该类位于“类的功能层次结构”的最上层。
在impl字段中保存的是实现了Display类的具体功能的实例。
该实例通过Display类的构造函数被传递给Display类,然后保存在impl字段中,以供后面的
处理使用(impl字段即是类的两个层次结构的“桥梁”)。
CountDisplay类
package bridge;
/**
* @author wenei
* @date 2021-05-24 12:04
*/
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();
}
}
CountDisplay类在Display类的基础上增加了一个新功能。Display类只具有“显示”的功能,CountDisplay类
则具有“只显示规定的次数”的功能,这就是multiDisplay方法。
CountDisplay类继承了Display类的open、print、close方法,并使用它们来增加这个新功能。
这就是“类的功能层次结构”。
DisplayImpl类
package bridge;
/**
* @author wenei
* @date 2021-05-24 12:02
*/
public abstract class DisplayImpl {
public abstract void rawOpen();
public abstract void rawPrint();
public abstract void rawClose();
}
DisplayImpl类位于“类的实现层次结构”的最上层。
DisplayImpl类是抽象类,它声明了rawOpen、rawPrint、rawClose这3个抽象方法,它们分别与
Display类的open、print、close方法相对应,进行显示前、显示、显示后处理。
StringDisplayImpl类
package bridge;
/**
* @author wenei
* @date 2021-05-24 12:05
*/
public class StringDisplayImpl extends DisplayImpl {
private String string;
private int width;
public StringDisplayImpl(String string) {
this.string = string;
this.width = string.getBytes().length;
}
@Override
public void rawOpen() {
printLine();
}
@Override
public void rawPrint() {
System.out.println("|" + string + "|");
}
@Override
public void rawClose() {
printLine();
}
private void printLine() {
System.out.print("+");
for (int i = 0; i < width; i++) {
System.out.print("-");
}
System.out.println("+");
}
}
StringDisplayImpl类是显示字符串的类。
不过,它不是直接的显示字符串,而是继承了DisplayImpl类,作为其子类来使用rawOpen、
rawPrint、rawClose方法进行显示。
DisplayImpl和StringDisplayImpl这两个类相当于“类的实现层次结构”。
Test类
package bridge;
/**
* @author wenei
* @date 2021-05-25 9:51
*/
public class Test {
public static void main(String[] args) {
Display display1 = new Display(new StringDisplayImpl("hello, China"));
Display display2 = new Display(new StringDisplayImpl("hello, World"));
CountDisplay countDisplay = new CountDisplay(new StringDisplayImpl("Hello, Universe"));
display1.display();
display2.display();
countDisplay.display();
countDisplay.multiDisplay(5);
}
}