前言

Github:https://github.com/HealerJean

博客:http://blog.healerjean.com

一、桥接(Bridge Pattern)设计模式

1、模式概述

桥接模式 是一种 结构型设计模式,它将 抽象部分(Abstraction)与其实现部分(Implementation)分离,使它们可以 独立变化。通过 组合(委托)代替继承,避免类爆炸问题,提升系统灵活性和可扩展性。

核心思想“抽象与实现解耦,各自独立演化。”

桥接模式 = 抽象 × 实现 → 组合它不是“硬编码组合”,而是“灵活装配”,让系统在多维变化中保持优雅。

2、使用场景

桥接模式适用于以下情况:

  • 不希望在抽象与其实现之间形成 固定的绑定关系
  • 抽象及其实现都应可通过 子类化独立扩展
  • 需要在运行时 动态切换实现
  • 类的继承层次会导致 组合爆炸(如 N 种形状 × M 种颜色 → N×M 个类)。

关键判断:如果你发现系统中存在 “多维度变化”(如平台 + 格式、形状 + 颜色、业务类型 + 支付方式),就该考虑桥接模式。

典型应用场景:

  • 跨平台 UI 控件(Windows/Linux/macOS × 按钮/文本框/列表);
  • 多格式媒体播放器(MP4/RMVB/AVI × Windows/Linux);
  • 多支付渠道 × 多业务场景(如单笔融资、多笔融资 × 微信/支付宝/银联)。

在实际开发中:

  • JDBC 驱动(DriverManager + 不同数据库驱动)是桥接的经典应用;
  • 小米融资系统中的 “单笔/多笔融资 × 票据类型” 正是桥接的实战体现;
  • 任何“平台 × 功能”、“主题 × 组件”、“业务 × 渠道”的场景,都值得考虑此模式。

3、示例程序 1:通用桥接结构

1565768485831

1)实现接口 Implementor

/**
 * 实现接口 —— 定义基本操作
 */
public interface Implementor {
    void operation();
}

2)具体实现类

public class ConcreteImplementorA implements Implementor {
    @Override
    public void operation() {
        System.out.println("ConcreteImplementorA 执行操作");
    }
}

public class ConcreteImplementorB implements Implementor {
    @Override
    public void operation() {
        System.out.println("ConcreteImplementorB 执行操作");
    }
}

3)抽象类 Abstraction

/**
 * 抽象类 —— 持有 Implementor 引用
 */
public abstract class Abstraction {
    
    protected Implementor implementor;

    public void setImplementor(Implementor implementor) {
        this.implementor = implementor;
    }

    public abstract void operation();
}

4)扩充抽象类 RefinedAbstraction

/**
 * 扩充抽象 —— 委托给 Implementor 执行具体逻辑
 */
public class RefinedAbstraction extends Abstraction {
    @Override
    public void operation() {
        // 可添加前后处理逻辑
        System.out.println("前置处理...");
        implementor.operation();
        System.out.println("后置处理...\n");
    }
}

5)客户端测试

效果:同一抽象对象可 在运行时绑定不同实现,行为动态变化。

public class Main {
    public static void main(String[] args) {
        Abstraction abstraction = new RefinedAbstraction();

        // 动态切换实现
        abstraction.setImplementor(new ConcreteImplementorA());
        abstraction.operation();

        abstraction.setImplementor(new ConcreteImplementorB());
        abstraction.operation();
    }
}

输出:

前置处理...
ConcreteImplementorA 执行操作
后置处理...

前置处理...
ConcreteImplementorB 执行操作
后置处理...

4、示例程序 2:跨平台视频播放器

1565768538795

1)实现接口 MediaPlayer

/**
 * 媒体播放器接口 —— 实现维度
 */
public interface MediaPlayer {
    void play();
}

2)具体播放器实现

public class Mp4Player implements MediaPlayer {
    @Override
    public void play() {
        System.out.println("使用 MP4 播放器播放视频");
    }
}

public class RmvbPlayer implements MediaPlayer {
    @Override
    public void play() {
        System.out.println("使用 RMVB 播放器播放视频");
    }
}

public class WmvPlayer implements MediaPlayer {
    @Override
    public void play() {
        System.out.println("使用 WMV 播放器播放视频");
    }
}

3)抽象平台 AbstractPlatform

/**
 * 平台抽象 —— 抽象维度
 */
public abstract class AbstractPlatform {
    
    protected MediaPlayer mediaPlayer;

    public void setMediaPlayer(MediaPlayer mediaPlayer) {
        this.mediaPlayer = mediaPlayer;
    }

    public abstract void playVideo();
}

4)具体平台实现

public class WindowsPlatform extends AbstractPlatform {
    @Override
    public void playVideo() {
        System.out.println("【Windows】启动视频播放:");
        mediaPlayer.play();
    }
}

public class LinuxPlatform extends AbstractPlatform {
    @Override
    public void playVideo() {
        System.out.println("【Linux】启动视频播放:");
        mediaPlayer.play();
    }
}

5)客户端测试

优势体现

  • 新增平台(如 macOS)?只需新增 MacPlatform
  • 新增格式(如 AVI)?只需新增 AviPlayer
  • 两者互不影响,组合自由
public class Main {
    public static void main(String[] args) {
        // Windows + MP4
        AbstractPlatform windows = new WindowsPlatform();
        windows.setMediaPlayer(new Mp4Player());
        windows.playVideo();

        // Windows + RMVB
        windows.setMediaPlayer(new RmvbPlayer());
        windows.playVideo();

        // Linux + WMV
        AbstractPlatform linux = new LinuxPlatform();
        linux.setMediaPlayer(new WmvPlayer());
        linux.playVideo();
    }
}

输出:

【Windows】启动视频播放:
使用 MP4 播放器播放视频
【Windows】启动视频播放:
使用 RMVB 播放器播放视频
【Linux】启动视频播放:
使用 WMV 播放器播放视频

5、FQA

1)模式优点

  • 解耦抽象与实现:两者可独立开发、测试、演进;
  • 避免类爆炸:从乘法(N×M)降为加法(N+M);
  • 支持运行时切换实现:灵活性高;
  • 符合单一职责原则:抽象关注“做什么”,实现关注“怎么做”。

2)注意事项

  • 增加系统复杂度:引入额外接口和组合关系;
  • 不适用于简单场景:若仅有一个实现,桥接反而过度设计;
  • 需提前识别多维度变化:设计初期就要预见扩展点。