桥接模式的作用是将类的功能层次结构
和类的实现层次结构
连接起来
假设现在有个Something
类,当我们想向它添加新功能时,可以编写一个它的子类,然后在子类中添加新的功能。这样就构成了类的功能结构。
当我们定义了一个抽象类,子类负责去实现这些抽象方法时,也形成了一个层次结构,这就叫类的实现层次结构。注意这里功能并没有增加,子类是为了具体实现抽象父类定义的方法。
试想有一个笔类,我们可以继承笔类,并向其添加画圆、画方等功能,这就是功能层次结构。假如我们要选择笔的颜色,那么我们可以在子类中添加方法来画出不同颜色的圆、方。现在我们要添加新功能画三角形,假设有12种颜色,那么为了添加这一个功能,又得重复写换颜色的12个方法。或者我们想添加新的颜色,那么又得修改所有的子类。这里功能层次结构和实现层次结构混杂在一起,难以扩展。
桥接模式可以将类的功能层次结构和类的实现层次结构分离。做到可以独立的修改功能及实现。
类图:
右边,CountDisplay
继承Display
,并添加了新的功能,这就是功能层次结构。
左边,StringDisplayImpl
实现了DisplayImpl
中的方法,这是类的实现层次结构。
这里Display
类持有一个DisplayImpl
的实例。这就连接了功能层次结构和实现层次结构。这样就可以独立的添加功能或者添加实现了。
代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20public 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();
}
}1
2
3
4
5
6
7
8
9
10
11
12public class CountDisplay extends Display {
public CountDisplay(DisplayImpl impl) {
super(impl);
}
public void multiDisplay(int times) { // 循环显示times次
open();
for (int i = 0; i < times; i++) {
print();
}
close();
}
}1
2
3
4
5public abstract class DisplayImpl {
public abstract void rawOpen();
public abstract void rawPrint();
public abstract void rawClose();
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24public class StringDisplayImpl extends DisplayImpl {
private String string; // 要显示的字符串
private int width; // 以字节单位计算出的字符串的宽度
public StringDisplayImpl(String string) { // 构造函数接收要显示的字符串string
this.string = string; // 将它保存在字段中
this.width = string.getBytes().length; // 把字符串的宽度也保存在字段中,以供使用。
}
public void rawOpen() {
printLine();
}
public void rawPrint() {
System.out.println("|" + string + "|"); // 前后加上"|"并显示
}
public void rawClose() {
printLine();
}
private void printLine() {
System.out.print("+"); // 显示用来表示方框的角的"+"
for (int i = 0; i < width; i++) { // 显示width个"-"
System.out.print("-"); // 将其用作方框的边框
}
System.out.println("+"); // 显示用来表示方框的角的"+"
}
}1
2
3
4
5
6
7
8
9
10
11public class Main {
public static void main(String[] args) {
Display d1 = new Display(new StringDisplayImpl("Hello, China."));
Display d2 = new CountDisplay(new StringDisplayImpl("Hello, World."));
CountDisplay d3 = new CountDisplay(new StringDisplayImpl("Hello, Universe."));
d1.display();
d2.display();
d3.display();
d3.multiDisplay(5);
}
}
结果: