1 概述
上一篇文章介绍了外观模式,接下来介绍桥接模式(Bridge Pattern)。桥接模式有时也被称为桥梁模式,也是一种常见结构模式,它主要体现了面向对象设计中的两个思想:
- 面向接口编程。
- 合成复用原则,即组合优先于继承。
2 桥接模式
桥接模式的目的是将抽象与实现分离,使二者能独立变化。说白了,其实就是:
- 给对象定义接口,来充当桥梁的作用。
- 调用者要依赖于目标对象的抽象(接口)而不是具体实现,更不是继承目标对象。
3 案例
开发者都有自己喜欢的IDE
,比如有人喜欢用Intellij
,有人喜欢用Eclipse
,其实这就涉及到两个维度:Developer
和IDE
,他们之间的变化是独立的,如何最好地表示它们之间的关系?如果用继承关系来做的话,那需要为每一个Developer
和IDE
的组合创建一个对象,比如JavaDeveloperWithEclipse
,JavaDeveloperWithIntellij
,显然这样做会大大增加系统复杂度。而如果用桥接模式来维护Developer
与IDE
的关系,将会变得简单很多:
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
public class Test {
public static void main(String[] args) {
// Developer与IDE的组合,完全由客户端来决定
IDE Intellij = new Intellij();
Developer nightfield = new JavaDeveloper(Intellij);
nightfield.coding();
IDE vim = new Vim();
Developer rocky = new JavaDeveloper(vim);
rocky.coding();
IDE vsCode = new VSCode();
Developer daisy = new PythonDeveloper(vsCode);
daisy.coding();
}
}
// 充当桥梁作用的接口
public interface IDE {
void run();
}
public class Intellij implements IDE {
@Override
public void run() { System.out.println("Intellij is running..."); }
}
public class Vim implements IDE {
@Override
public void run() { System.out.println("Vim is running..."); }
}
public class VSCode implements IDE {
@Override
public void run() { System.out.println("VSCode is running..."); }
}
// Developer只依赖于IDE接口而不关心其实现
public abstract class Developer {
// 组合关系,持有IDE的实例,而且只依赖于IDE的接口而不是实现
protected IDE ide;
// 强制在构造方法中传入IDE的实例
Developer(IDE ide) {
this.ide = ide;
}
abstract void coding();
}
public class JavaDeveloper extends Developer {
JavaDeveloper(IDE ide) {
super(ide);
}
void coding() {
ide.run();
System.out.println("Java developer is coding...");
};
}
public class PythonDeveloper extends Developer {
PythonDeveloper(IDE ide) {
super(ide);
}
void coding() {
ide.run();
System.out.println("Python developer is coding...");
};
}
输出:
1
2
3
4
5
6
Intellij is running...
Java developer is coding...
Vim is running...
Java developer is coding...
VSCode is running...
Python developer is coding...
这个例子中的桥梁,就是IDE
接口。所谓抽象与实现分离,体现在Developer
与IDE
是组合关系,而且只依赖于IDE
接口而不依赖于它的实现,耦合度低,使得Developer
和IDE
可以独立变化。可以遇见,无论之后对模块做什么修改,或者模块增加另外的实现,都不会影响到其他的模块。
我们熟悉的JDBC
中,就运用了桥接模式。DriverManager
代表了桥梁中的JDK
一端,Driver
的实现(如OracleDriver
)代表了桥梁的数据库供应商一端,而Driver
接口充当了桥梁的角色,JDK
可是要“兼容”所有的数据库的,才不关心Driver
的连接细节呢。
4 总结
桥接模式的核心是面向接口编程,组合优先于继承。合理运用桥接模式,可以降低类之间的耦合度,从而降低系统的复杂度,提供可维护性。