Zer0e's Blog

设计模式之桥接模式

字数统计: 1.2k阅读时长: 4 min
2020/09/04 Share

前言

桥接模式其实是很少在项目中使用的设计模式,难度可以说是很大的。但是理解桥接模式能更深入的理解面向对象编程。
那这篇就来讲讲这个模式。

正文

概念

我们先来看看维基百科上的定义:

桥接模式是软件设计模式中最复杂的模式之一,它把事物对象和其具体行为、具体特征分离开来,使它们可以各自独立的变化。

听起来就很复杂,而且竟然说是最复杂的设计模式。
桥的作用就是连接河的两岸,那么桥接是不是也有关系呢?是的,桥接就是为了连接两个独立结构,而这两个独立结构可以独立的发生变化。
那这个设计模式的目的就是为了将抽象部分与实现部分分离,使他们可以独立的变化,这个抽象与实现部分就是我们上面所说的两个独立结构。
总结一下,这个设计模式解决的有以下几点:

  • 如果系统需要在抽象化和具体化之间更加灵活的转换,避免了两个层次之间建立静态的继承关系,此时通过桥接模式能是他们建立联系。
  • 当使用多层次继承时,会导致系统类的增多导致类爆炸,那使用桥接模式是不错的选择。
  • 当一个类可能有多个变化的方向时,并且这几个变化方向都各自独自,那桥接模式就排上用场了。

实现

由于图床实在是不方便,所以我没有放UML图,我这里还是简单实现个小例子吧。
首先桥接模式涉及到的角色有以下几个:

  • Abstraction:抽象接口
  • RefinedAbstraction:拓展Abstraction
  • Implementor:具体的实现接口,它和RefinedAbstraction中的接口不一定相同
  • ConcreteImplementor:实现Implementor接口

一个简单小例子,比如乘坐交通工具出门旅游,可能有多个目的地的变化,比如杭州,上海等,然后出门的交通工具也可以不同,比如小轿车自驾,或者做飞机。
那以上代码如何去实现桥接呢?
首先我们定义Implementor,那对应到这个例子就是交通工具。为啥先定义具体接口呢?原因是因为在Abstraction会将Implementor作为对象注入。

1
2
3
public interface Vehicle {
public void ride();
}

接下来是具体的交通工具(ConcreteImplementor)

1
2
3
4
5
6
7
8
9
10
11
12
public class Car implements Vehicle{
@Override
public void ride() {
System.out.println("乘坐小轿车");
}
}
public class AirPlane implements Vehicle{
@Override
public void ride() {
System.out.println("乘坐飞机");
}
}

那接下来就是抽象对象接口(Abstraction),这例子中就是我们的目的地。

1
2
3
4
5
6
7
8
9
public abstract class City {
protected Vehicle vehicle;

public City(Vehicle vehicle) {
this.vehicle = vehicle;
}

public abstract void visit();
}

具体的目的地

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class HangZhou extends City{
public HangZhou(Vehicle vehicle) {
super(vehicle);
}

@Override
public void visit() {
super.vehicle.ride();
System.out.println("到杭州旅游");
}
}
public class ShangHai extends City{
public ShangHai(Vehicle vehicle) {
super(vehicle);
}

@Override
public void visit() {
super.vehicle.ride();
System.out.println("到上海旅游");
}
}

我们写个测试代码

1
2
3
4
5
6
7
8
9
public class Main {
public static void main(String[] args) {
City city = new ShangHai(new AirPlane());
city.visit();

City city1 = new HangZhou(new Car());
city1.visit();
}
}

如此我们便将抽象部分与实现部分相分离,比如当类发生改变时,两者互不影响。比如交通工具增多,那对于City是没什么影响的,反过来,City增多也不影响交通工具。

优缺点

优点很明显,就是抽象与实现的分离,并且扩展性强,而且具体的实现对调用者是透明的。
而缺点就是这个模式理解起来有难度,对于维护可能会加重,并且由于建立在抽象编程上,开发者需要深入面向对象编程才能理解。

总结

那简单总结一下

  • 如果抽象和实现部分不想耦合性那么强,那么可以采用桥接模式,将两个部分分开来。
  • 如果两个部分都需要单独的扩展,可以使用桥接模式,两部分都可以独立的变化,并且互不影响。
  • 当修改实现类时,不希望对调用方产生影响,那可以采用桥接模式,因为调用方是面向接口的,如果具体的实现类修改时,调用方不受影响,可以说是对调用方是透明的。
  • 当我们采用继承时,可能会有很多子类,比如C继承B,B继承A,多级继承时,那采用桥接模式可以减少子类的数目。

那以上就是这篇文章的内容,全文写下来觉得这个模式虽然很晦涩,但只要多写写代码就能理解。

CATALOG
  1. 1. 前言
  2. 2. 正文
    1. 2.1. 概念
    2. 2.2. 实现
    3. 2.3. 优缺点
    4. 2.4. 总结