Skip to content

桥接模式 (Bridge Pattern) ​

模式定义 ​

桥接模式是一种结构型设计模式,它将抽象部分与实现部分分离,使它们都可以独立变化。桥接模式用组合/聚合关系代替继承关系,降低了抽象和实现这两个可变维度的耦合度。

核心概念 ​

  • 抽象 (Abstraction): 定义抽象类的接口,维护一个实现部分的引用
  • 扩展抽象 (Refined Abstraction): 扩展抽象类,改变和修正父类的行为
  • 实现 (Implementor): 定义实现类的接口
  • 具体实现 (Concrete Implementor): 具体实现类

实现示例:Shape × Color 系统 ​

实现接口(颜色维度) ​

java
// 颜色实现接口
public interface Color {
    String fill();
}

// 红色
public class Red implements Color {
    @Override
    public String fill() {
        return "红色";
    }
}

// 蓝色
public class Blue implements Color {
    @Override
    public String fill() {
        return "蓝色";
    }
}

// 绿色
public class Green implements Color {
    @Override
    public String fill() {
        return "绿色";
    }
}

抽象部分(形状维度) ​

java
// 形状抽象类
public abstract class Shape {
    // 桥接:持有颜色实现的引用
    protected Color color;

    protected Shape(Color color) {
        this.color = color;
    }

    public abstract void draw();
}

// 圆形
public class Circle extends Shape {
    public Circle(Color color) {
        super(color);
    }

    @Override
    public void draw() {
        System.out.println("画一个" + color.fill() + "的圆形");
    }
}

// 矩形
public class Rectangle extends Shape {
    public Rectangle(Color color) {
        super(color);
    }

    @Override
    public void draw() {
        System.out.println("画一个" + color.fill() + "的矩形");
    }
}

// 三角形
public class Triangle extends Shape {
    public Triangle(Color color) {
        super(color);
    }

    @Override
    public void draw() {
        System.out.println("画一个" + color.fill() + "的三角形");
    }
}

使用示例 ​

java
public class BridgeDemo {
    public static void main(String[] args) {
        // 红色圆形
        Shape redCircle = new Circle(new Red());
        redCircle.draw();

        // 蓝色矩形
        Shape blueRectangle = new Rectangle(new Blue());
        blueRectangle.draw();

        // 绿色三角形
        Shape greenTriangle = new Triangle(new Green());
        greenTriangle.draw();

        // 动态组合
        Shape[] shapes = {
            new Circle(new Red()),
            new Circle(new Blue()),
            new Rectangle(new Red()),
            new Rectangle(new Green()),
            new Triangle(new Blue()),
            new Triangle(new Green())
        };

        System.out.println("\n所有形状:");
        for (Shape shape : shapes) {
            shape.draw();
        }
    }
}

实现示例:遥控器 × 设备系统 ​

实现接口(设备维度) ​

java
// 设备接口
public interface Device {
    void on();
    void off();
    void volumeUp();
    void volumeDown();
    int getVolume();
}

// 电视
public class TV implements Device {
    private int volume = 50;
    private boolean on = false;

    @Override
    public void on() {
        on = true;
        System.out.println("电视已开机");
    }

    @Override
    public void off() {
        on = false;
        System.out.println("电视已关机");
    }

    @Override
    public void volumeUp() {
        if (volume < 100) volume += 10;
        System.out.println("电视音量: " + volume);
    }

    @Override
    public void volumeDown() {
        if (volume > 0) volume -= 10;
        System.out.println("电视音量: " + volume);
    }

    @Override
    public int getVolume() {
        return volume;
    }
}

// 收音机
public class Radio implements Device {
    private int volume = 30;
    private boolean on = false;

    @Override
    public void on() {
        on = true;
        System.out.println("收音机已开机");
    }

    @Override
    public void off() {
        on = false;
        System.out.println("收音机关机");
    }

    @Override
    public void volumeUp() {
        if (volume < 100) volume += 5;
        System.out.println("收音机音量: " + volume);
    }

    @Override
    public void volumeDown() {
        if (volume > 0) volume -= 5;
        System.out.println("收音机音量: " + volume);
    }

    @Override
    public int getVolume() {
        return volume;
    }
}

抽象部分(遥控器维度) ​

java
// 遥控器抽象类
public abstract class RemoteControl {
    protected Device device;

    protected RemoteControl(Device device) {
        this.device = device;
    }

    public abstract void powerOn();
    public abstract void powerOff();
    public abstract void volumeUp();
    public abstract void volumeDown();
}

// 基础遥控器
public class BasicRemote extends RemoteControl {
    public BasicRemote(Device device) {
        super(device);
    }

    @Override
    public void powerOn() {
        System.out.print("基础遥控器 - ");
        device.on();
    }

    @Override
    public void powerOff() {
        System.out.print("基础遥控器 - ");
        device.off();
    }

    @Override
    public void volumeUp() {
        device.volumeUp();
    }

    @Override
    public void volumeDown() {
        device.volumeDown();
    }
}

// 高级遥控器(带静音功能)
public class AdvancedRemote extends RemoteControl {
    private boolean muted = false;

    public AdvancedRemote(Device device) {
        super(device);
    }

    @Override
    public void powerOn() {
        System.out.print("高级遥控器 - ");
        device.on();
    }

    @Override
    public void powerOff() {
        System.out.print("高级遥控器 - ");
        device.off();
    }

    @Override
    public void volumeUp() {
        if (!muted) {
            device.volumeUp();
        }
    }

    @Override
    public void volumeDown() {
        if (!muted) {
            device.volumeDown();
        }
    }

    public void mute() {
        muted = !muted;
        System.out.println("静音: " + (muted ? "开启" : "关闭"));
    }
}

使用示例 ​

java
public class BridgeDemo2 {
    public static void main(String[] args) {
        // 基础遥控器控制电视
        RemoteControl tvRemote = new BasicRemote(new TV());
        tvRemote.powerOn();
        tvRemote.volumeUp();
        tvRemote.volumeUp();
        tvRemote.powerOff();

        System.out.println("---");

        // 高级遥控器控制收音机
        AdvancedRemote radioRemote = new AdvancedRemote(new Radio());
        radioRemote.powerOn();
        radioRemote.volumeUp();
        radioRemote.mute();
        radioRemote.volumeUp(); // 静音状态下不会调音量
        radioRemote.mute();
        radioRemote.volumeUp();
    }
}

JDBC 中的桥接模式 ​

java
// JDBC 就是典型的桥接模式
// Driver 是实现部分,Connection 是抽象部分
// 不同的数据库驱动 (MySQL, Oracle) 提供不同的实现
Connection conn = DriverManager.getConnection(url, user, password);

不使用桥接 vs 使用桥接 ​

不使用桥接模式时,Shape × Color 需要 3 × 3 = 9 个类:

RedCircle, BlueCircle, GreenCircle
RedRectangle, BlueRectangle, GreenRectangle
RedTriangle, BlueTriangle, GreenTriangle

使用桥接模式后,只需要 3 + 3 = 6 个类:

Shape: Circle, Rectangle, Triangle
Color: Red, Blue, Green

优缺点 ​

优点:

  • 分离抽象和实现,可以独立变化
  • 符合开闭原则
  • 减少类的数量,避免多层继承

缺点:

  • 增加系统理解难度
  • 需要正确识别两个独立变化的维度

适用场景 ​

  • 需要在多个维度上扩展的系统
  • 不希望使用多层继承导致类爆炸
  • 需要在运行时切换实现