桥接模式

桥接模式

一、什么是桥接模式?

桥接模式(Bridge Design Pattern):将抽象与实现解耦,让他们能够独立变化。

或者,桥接模式就是将类的功能层次结构和类的实现层次结构分离开来,降低它们的耦合度。

抽象,即类的功能层次结构,采用的是继承的方式。

实现,即类的实现层次结构,采用的是组合的方式。

1.1 多用组合少用继承

桥接模式,还有通俗一些的解释:一个类存在多个独立变化的维度时,可以通过组合方式让这些维度独立扩展。

比如说,汽车 Car 是一种抽象类型。

它的品牌类型,可以是奔驰、宝马、奥迪等;

而每辆车,它可能有好几个挡位,比如自动档、手动挡、手自一体等。

假设有m种品牌,n种挡位,那么它既可以形成成 m * n 种组合。

如果只采用继承来实现这些组合的话,那就需要有 m * n 个类,如果还有其他维度,那么组合数量会更多。

但是通过桥接模式,将品牌和挡位分离,采用组合的方式的话,就只需要 m + n 个类,大大减少了类的数量。

桥接模式,实际上就是利用组合来避免继承爆炸。

1.2 基于接口编程

如果从结构上来说的话,继承就相当于是一棵树,组合就相当于在树与树之间的连接,它们构成了森林。

每棵树,都是一个维度,都有自己的抽象功能层次结构;

而每个维度之间,又存在着联系,这种联系就是一种实现层次。

树与树之间的联系,一般都是通过顶层的接口抽象来关联的,互相之间是基于接口连接。

桥接模式,实际上是通过接口来进行交互。

二、为什么要用桥接模式?

桥接模式的主要作用有几个:

  • 将类的功能层次和实现层次分离,降低耦合度
  • 使用组合替代继承,避免组合爆炸的问题
  • 把各个维度独立出来,方便进行扩展

使用桥接模式,最主要的就是避免类继承层次过深,而采用组合的方式来避免这种情况。

比如说,有m个维度,每个维度有n种变化,每种变化又包含k种情况,采用继承来做,就需要 m * n * k 个类。

如果将各个维度独立开来,采用组合的方式,就只需要 m + n + k 个类。

而且各个维度可以单独变化扩展,可维护性也会增强。

桥接模式适用于类层次和类关联比较复杂的情况,如果类层次结构很简单,使用桥接模式反而过于复杂。

三、怎么用桥接模式?

桥接模式中的几个角色:

  • 抽象化(Abstraction):类功能层次的抽象类,里面包含了一个实现者的引用
  • 扩展后的抽象化(Refined Abstraction):在抽象化的基础上扩展了新功能
  • 实现者(Implementor):类实现层次的抽象类,被抽象化角色包含在内
  • 具体实现者(ConcreteImplememtor):是实现者的具体实现

桥接模式结构:

桥接模式结构

示例程序结构:

桥接模式结构

抽象化(Abstraction):

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 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();
}

}

扩展后的抽象化(Refined Abstraction):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class CountDisplay extends Display {

public CountDisplay(DisplayImpl impl) {
super(impl);
}

public void multiDisplay(int times) {
open();
for (int i = 0; i < times; i++) {
print();
}
close();
}
}

实现者(Implementor):

1
2
3
4
5
6
7
public abstract class DisplayImpl {

public abstract void rawOpen();
public abstract void rawPrint();
public abstract void rawClose();

}

具体实现者(ConcreteImplememtor):

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
public class StringDisplayImpl extends DisplayImpl {

private String string;
private int width;

public StringDisplayImpl(String string) {
this.string = string;
this.width = string.getBytes().length;
}

@Override
public void rawOpen() {
printLine();
}

@Override
public void rawPrint() {
System.out.println("|" + string + "|");
}

@Override
public void rawClose() {
printLine();
}

private void printLine() {
System.out.print("+");
for (int i = 0; i < width; i++) {
System.out.print("-");
}
System.out.println("+");
}
}

四、桥接模式有什么优缺点?

优点:

  • 将类的功能层次和实现层次分离,降低耦合度
  • 使用组合替代继承,避免组合爆炸的问题
  • 把各个维度独立出来,方便进行扩展

缺点:

  • 结构变得复杂了,可读性变差了
作者

jiaduo

发布于

2022-01-17

更新于

2023-04-03

许可协议