结构型-桥接模式
# 什么是桥接模式?
- 第一种解释:将抽象和实现解耦,让他们可以独立变化。
- 需要弄懂“抽象”和“实现”的两个概念。
- 定义中的“抽象”,指的并非“抽象类”或“接口”,而是被抽象出来的一套“类库”,它只包含骨架代码,真正的业务逻辑需要委派给定义中的实现来完成。
- 定义中的实现也并非“接口的实现类”,而是一套独立的“类库”。
- 抽象和实现独立开发,通过对象之间的组合关系,组装在一起。
- 第二种解释:一个类存在两个(或多个)独立变化的维度,我们通过组合的方式,让这两个(或多个)维度可以独立进行扩展。
- 通过组合关系来替代继承关系,避免继承层次的指数级爆炸。
# 为什么使用桥接模式?
- 将抽象和实现隔离开,例如 Java 中的 java.sql.Driver 类,定义了 JDBC 的抽象,而具体的实现需要各种数据库自定义实现,进行适配。
- 这样我们在使用不同的数据库时,只需替换不同 Driver 声明即可,对于其余部分,不用修改。
- JDBC 本身就相当于“抽象”。注意,这里所说的“抽象”,指的并非“抽象类”或“接口”,而是跟具体的数据库无关的、被抽象出来的一套“类库”。
Class.forName("com.mysql.jdbc.Driver");//加载及注册JDBC驱动程序
String url = "jdbc:mysql://localhost:3306/sample_db?user=root&password=your_password";
Connection con = DriverManager.getConnection(url);
Statement stmt = con.createStatement();
String query = "select * from test";
ResultSet rs=stmt.executeQuery(query);
while(rs.next()) {
rs.getString(1);
rs.getInt(2);
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 什么情况使用桥接模式?
- 需要一个抽象 lib 和一个实现 lib,类似 JDBC。
- 多个维度时,避免使用继承出现指数级爆炸问题,使用组合。
# 桥接模式好处
- 桥接模式优化了原先使用继承时的子类爆炸问题,同时优化实现结构,转化为两层,使用组合模式
Has-A
而不是Is-A
。 - 使得在抽象功能和原先具体实现双方解耦,进行版本升级的时候会互不影响。
- 抽象和具体实现解耦。
- 抽象和具体实现解耦。
- 抽象和具体实现解耦。
- 允许抽象和实现同时发展,最后将实现传入的到抽象中,进行调用。
# 代码实现
public interface MsgSender {
void send(String message);
}
public class TelephoneMsgSender implements MsgSender {
private List<String> telephones;
public TelephoneMsgSender(List<String> telephones) {
this.telephones = telephones;
}
@Override
public void send(String message) {
//...
}
}
public class EmailMsgSender implements MsgSender {
// 与TelephoneMsgSender代码结构类似,所以省略...
}
public class WechatMsgSender implements MsgSender {
// 与TelephoneMsgSender代码结构类似,所以省略...
}
public abstract class Notification {
protected MsgSender msgSender;
public Notification(MsgSender msgSender) {
this.msgSender = msgSender;
}
public abstract void notify(String message);
}
public class SevereNotification extends Notification {
public SevereNotification(MsgSender msgSender) {
super(msgSender);
}
@Override
public void notify(String message) {
msgSender.send(message);
}
}
public class UrgencyNotification extends Notification {
// 与SevereNotification代码结构类似,所以省略...
}
public class NormalNotification extends Notification {
// 与SevereNotification代码结构类似,所以省略...
}
public class TrivialNotification extends Notification {
// 与SevereNotification代码结构类似,所以省略...
}
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
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
上次更新: 2020/09/08, 15:09:00