> 本部分内容参见[这里](https://baijiahao.baidu.com/s?id=1639383166201396225&wfr=spider&for=pc)

## 定义

桥接模式（Bridge Pattern），将抽象部分与它的实现部分分离，使它们都可以独立地变化。更容易理解的表述是：实现系统可从多种维度分类，桥接模式将各维度抽象出来，各维度独立变化，之后可通过聚合，将各维度组合起来，减少了各维度间的耦合。

## 示例

我们都去买过手机，手机按照品牌分可以分为华为、小米、OPPO、vivo 等品牌，如果这些手机按照内存分又可以分为 4 G、6 G、8 G等等。假如我们每一种手机都想要玩一下，至少需要 4×3 个。这对我们来说这些手机也太多了，竟然有 12 个，最主要的是手机品牌和内存是放在一起的。现在有这样一种机制，手机牌品商是一个公司，做手机内存的是一个公司，想要做什么手机我们只需要让其两者搭配起来即可。有点类似于全球贸易分工明确的思想，这就是桥接模式，把两个不同维度的东西桥接起来。

从上面的例子我们可以看到，我们的手机可以从两个维度进行变化，一个是品牌，一个是内存。此时我们就可以通过桥接模式将这两个维度分离开来，每一个维度都可以独立扩展。比如说手机品牌，可以又出现了苹果、三星、锤子等等。内存方面又可以生产 10 G、16 G 的了。从专业的角度来看可以这样定义桥接模式：

> 桥接模式是一种很实用的结构型设计模式，如果软件系统中某个类存在两个独立变化的维度，通过该模式可以将这两个维度分离出来，使两者可以独立扩展，让系统更加符合“单一职责原则”。

上面的例子我们画一张类图来表示一下：

![](img/01.jpeg)

基本上意思就是这，也就是我们买手机的时候有两个维度可供我们选择:一个是品牌一个是内存。

（1）Client：指的是我们买手机的人

（2）Abstraction（抽象类）：指的是手机抽象类

（3）Refined Abstraction（具体类）：指的是具体手机品牌

（4）Implementor：在这里相当于手机的其他组件，内存

（5）Concrete Implementor：具体的内存型号

## 实现

第一步：定义 Implementor，这里定义手机内存接口

```java
public interface Memory {
    void addMemory();
}
```

第二步：定义 Concrete Implementor，这里指具体的内存

内存这里定义了两种一种是 6 G，一种是 8 G

```java
public class Memory6G implements Memory{
    @Override
    public void addMemory() {
        System.out.println("手机安装了6G内存");
    }
}
// ---------------------------------------
public class Memory8G implements Memory{
    @Override
    public void addMemory() {
        System.out.println("手机安装了8G内存");
    }
}
```

第三步：定义 Abstraction 手机抽象类

```java
public abstract class Phone {
    protected Memory phoneMemory;

    public void setPhoneMemory(Memory phoneMemory) {
        this.phoneMemory = phoneMemory;
    }
    public abstract void buyPhone();
}
```

第四步：定义Refined Abstraction（具体的手机品牌）

首先是华为

```java
public class HuaWei extends Phone{
    @Override
    public void buyPhone() {
        phoneMemory.addMemory();
        System.out.println("购买华为手机");
    }
}
```

然后是小米

```java
public class Mi extends Phone{
    @Override
    public void buyPhone() {
        phoneMemory.addMemory();
        System.out.println("购买小米手机");
    }
}
```

第五步：测试一下

```java
public class Client {
    public static void main(String[] args) {
        // 华为8G手机
        System.out.println("====== 华为8G手机 ======");
        HuaWei huaWei = new HuaWei();
        huaWei.setPhoneMemory(new Memory8G());
        huaWei.buyPhone();
        // 小米6G手机
        System.out.println("====== 小米6G手机 ======");
        Mi mi = new Mi();
        mi.setPhoneMemory(new Memory6G());
        mi.buyPhone();
    }
}
```

```
====== 华为8G手机 ======
手机安装了8G内存
购买华为手机
====== 小米6G手机 ======
手机安装了6G内存
购买小米手机
```

从代码就可以看出，购买手机的时候，品牌和内存两个维度是分开的。下面我们分析一下这个桥接模式

## 分析桥接模式

### 为什么使用桥接模式不使用继承呢？

继承是一种强耦合关系，子类与父类有非常紧密的依赖关系，父类的任何变化都会导致子类发生变化。因此才使用桥接模式，使用了桥接模式之后，我们的两个维度就像桥梁一样被链接了起来。体现了松耦合的特性。

### 桥接模式的优点

1. 分离抽象和实现部分：把手机、内存抽象出来。实现与之分离。
2. 松耦合：两个维度分开
3. 单一职责原则：每个维度各干各的活

关于桥接模式的使用场景我觉得你只需要知道他的思想，然后在遇到问题的时候能够想到这种模式即可。











