桥接模式

概述

在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维度的变化”?如何利用面向对象的技术来使得该类型能够轻松的沿着多个方向进行变化,而又不引入额外的复杂度?这就要使用Bridge模式。

意图

将抽象部分与实现部分分离,使它们都可以独立的变化。

结构图

结构图

模仿手机安装软件的例子

新建手机和应用类

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
public abstract class Phone {
protected String name;
protected Application app;
public Phone(String name) {
this.name = name;
}
public void installApp(Application app) {
System.out.println(name + ": " + app.name + " is installing");
this.app = app;
}
public abstract void run();
}
public abstract class Application {
protected String name;
public Application(String name) {
this.name = name;
}
public abstract void run();
}

手机具体实现类

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
public class Android extends Phone {
public Android(String name) {
super(name);
}
@Override
public void run() {
System.out.print(name + ": ");
app.run();
}
}
public class Apple extends Phone {
public Apple(String name) {
super(name);
}
@Override
public void run() {
System.out.print(name + ": ");
app.run();
}
}

应用具体实现类

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
public class AddressList extends Application {
public AddressList(String name) {
super(name);
}
@Override
public void run() {
System.out.println("running app: " + name);
}
}
public class Camera extends Application {
public Camera(String name) {
super(name);
}
@Override
public void run() {
System.out.println("running app: " + name);
}
}

客户端实现代码

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
public class Client {
public static void main(String[] args) {
Phone phone = new Android("小米5");
phone.installApp(new AddressList("通讯录"));
phone.run();
System.out.println();
phone.installApp(new Camera("相机"));
phone.run();
System.out.println();
phone = new Apple("iPhone 6s");
phone.installApp(new AddressList("通讯录"));
phone.run();
System.out.println();
phone.installApp(new Camera("相机"));
phone.run();
System.out.println();
}
}

运行结果

1
2
3
4
5
6
7
8
9
10
11
小米5: 通讯录 is installing
小米5: running app: 通讯录
小米5: 相机 is installing
小米5: running app: 相机
iPhone 6s: 通讯录 is installing
iPhone 6s: running app: 通讯录
iPhone 6s: 相机 is installing
iPhone 6s: running app: 相机

扩展程序:新增应用

只需增加一个实现类
1
2
3
4
5
6
7
8
9
10
11
12
public class MusicPlayer extends Application {
public MusicPlayer(String name) {
super(name);
}
@Override
public void run() {
System.out.println("running app: " + name);
}
}
修改客户端代码:
1
2
3
4
5
6
7
phone.installApp(new MusicPlayer("网易云音乐"));
phone.run();
System.out.println();
phone.installApp(new MusicPlayer("天天动听"));
phone.run();
System.out.println();
运行结果
1
2
3
4
5
iPhone 6s: 网易云音乐 is installing
iPhone 6s: running app: 网易云音乐
iPhone 6s: 天天动听 is installing
iPhone 6s: running app: 天天动听