It has been 570 days since the last update, the content of the article may be outdated.

桥接模式(Bridge)

桥接模式也称为桥梁模式、接口模式或者柄体(Handle and Body)模式,是将抽象部分与他的具体实现部分分离,使它们都可以独立地变化,通过组合的方式建立两个类之间的联系,而不是继承。

简单理解的话:可以想象成通过一个桥梁把两个原本属于继承关系的类,给他改为了组合关系,变得更灵活。

什么情况适合用桥接模式:

在继承关系的基础上又需要灵活多变的两个和两个以上的子类,那么就可以用桥接模式,利用组合达到灵活多变的效果。

角色

桥接(Bridge)模式包含以下主要角色:

  • 抽象化(Abstraction)角色 :定义抽象类,并包含一个对实现化对象的引用。
  • 扩展抽象化(Refined Abstraction)角色 :是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。
  • 实现化(Implementor)角色 :定义实现化角色的接口,供扩展抽象化角色调用。
  • 具体实现化(Concrete Implementor)角色 :给出实现化角色接口的具体实现。

示例代码

不用桥接模式

java
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
// 电脑品牌
public interface Brand {
void info();
}
// 戴尔电脑品牌
public class Dell implements Brand {
@Override
public void info() {
System.out.print("戴尔电脑");
}
}
// 联想电脑品牌
public class Lenovo implements Brand {
@Override
public void info() {
System.out.println("联想电脑");
}
}
// 电脑又分台式机和笔记本
// 台式机
public class DellDesktop extends Dell {
@Override
public void info() {
super.info();
System.out.println("台式机");
}
}
// 笔记本
public class DellNoteBook extends Dell{
@Override
public void info() {
super.info();
System.out.println("笔记本");
}
}

public class Main {
public static void main(String[] args) {
Brand dellDesktop = new DellDesktop();
dellDesktop.info();
Brand dellNoteBook = new DellNoteBook();
dellNoteBook.info();

}
}

其他品牌的我就不写了,如果我们按照这样去写的话,2*3=6要多写6个类,如果我们后续又要增强新品牌,是不是又要写这些重复的类呢

用桥接模式

java
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
63
64
65
66
67
68
69
70
71
72
73
74
75
// 电脑品牌 抽象化角色
public interface Brand {
void info();
}

// 扩展抽象化角色
// 戴尔电脑品牌
public class Dell implements Brand {
@Override
public void info() {
System.out.print("戴尔电脑");
}
}
// 联想电脑品牌
public class Lenovo implements Brand {
@Override
public void info() {
System.out.println("联想电脑");
}
}

// 实现化角色 桥接点
public abstract class Computer {
private Brand brand; // 组合

public Computer(Brand brand) {
this.brand = brand;
}
public void info(){
brand.info(); // 自带的品牌
}
}

//具体实现化角色
// 台式机
public class Desktop extends Computer {
public Desktop(Brand brand) {
super(brand);
}

@Override
public void info() {
super.info();
System.out.println("台式机");
}
}
// 笔记本
public class NoteBook extends Computer {
public NoteBook(Brand brand) {
super(brand);
}
@Override
public void info() {
super.info();
System.out.println("笔记本");
}
}


public class Main {
public static void main(String[] args) {
// 戴尔电脑台式机
Computer dellDesktop = new Desktop(new Dell());
dellDesktop.info();
// 戴尔电脑笔记本
Computer dellNoteBook = new NoteBook(new Dell());
dellNoteBook.info();
// 联想电脑台式机
Computer Lenovo = new Desktop(new Lenovo());
Lenovo.info();
// 联想电脑笔记本
Computer Lenovo1 = new NoteBook(new Lenovo());
Lenovo1.info();
}
}

这样是不是就可以减少了很多类呢?同时更加灵活。

另外一个例子:

java
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
// 视频接口
public interface Video {
void decode(String fileName);
}

// MP4格式类
public class Mp4 implements Video{
@Override
public void decode(String fileName) {
System.out.println("MP4视频文件:"+ fileName);
}
}
// RMVB格式类
public class Rmvb implements Video{
@Override
public void decode(String fileName) {
System.out.println("rmvb文件:" + fileName);
}
}
// 操作系统抽象类 桥接点
@AllArgsConstructor
public abstract class OperatingSystem {
Video video;
public abstract void play(String fileName);

}
// iOS系统
public class Ios extends OperatingSystem {
public Ios(Video video){
super(video);
}
@Override
public void play(String fileName) {
video.decode(fileName);
}
}
// windows系统
public class Windows extends OperatingSystem {
public Windows(Video video){
super(video);
}
@Override
public void play(String fileName) {
video.decode(fileName);
}
}

总结

适用场景:

  • 在抽象和具体实现之间需要增加更多的灵活性的场景。
  • 一个类存在两个(或多个)独立变化的维度,而这两个(或多个)维度都需要独立进行扩展。
  • 不希望使用继承,或因为多层继承导致系统类的个数剧增。

优点:

  • 分离抽象部分及其具体实现部分。
  • 提高了系统的扩展性。
  • 符合开闭原型。
  • 符合合成复用原则。

缺点:

  • 增加了系统的理解与设计难度。
  • 需要正确地识别系统中两个独立变化的维度。