JavaDog程序狗
发布于 2026-11-05 / 1 阅读
0
0

【设计模式】跟着狗哥复习设计模式(七):桥接模式

狗哥家电店里有电视,也有音响。柜台上还有普通遥控器和带静音键的遥控器。

遥控器会变,设备也会变。要是把它们全揉进一套继承关系,类很快就多起来。

桥接模式就是把这两边拆开,中间留一座桥。

加瓦狗在家电店演示遥控器控制电视和音响

两个方向都在变化

现在有两种遥控器、两种设备。

最直接的写法,可能会出现电视遥控器、音响遥控器、电视静音遥控器、音响静音遥控器。

遥控器和设备组合导致类数量增加

再加投影仪,类还得继续补。问题不在某个类难写,而是两个变化方向绑得太紧。

先看关键 UML 图

桥接模式最适合先看类图。

桥接模式关键 UML 类图

上面一条是遥控器:RemoteControl 可以继续扩展出 MuteRemoteControl。

下面一条是设备:Device 可以有 Tv、Speaker 等实现。

RemoteControl 持有一个 Device。这条组合关系,就是两边的桥。

设备先统一成接口

电视和音响虽然不同,但遥控器需要的操作差不多:开关和音量。

public interface Device {
    boolean isEnabled();
    void enable();
    void disable();
    int getVolume();
    void setVolume(int volume);
}

Tv 和 Speaker 分别实现这个接口。

public class Tv implements Device {
    private boolean enabled;
    private int volume = 10;

    public void enable() { enabled = true; }
    public void disable() { enabled = false; }
    public boolean isEnabled() { return enabled; }
    public int getVolume() { return volume; }
    public void setVolume(int volume) { this.volume = volume; }
}

电视和音响实现同一个 Device 接口

遥控器只认 Device,不用知道背后是电视还是音响。

遥控器把操作交给设备

RemoteControl 构造时接收一个设备。

public class RemoteControl {
    protected final Device device;

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

    public void togglePower() {
        if (device.isEnabled()) {
            device.disable();
        } else {
            device.enable();
        }
    }

    public void volumeUp() {
        device.setVolume(device.getVolume() + 10);
    }
}

遥控器把调用转交给设备

遥控器负责“按哪个键”,设备负责“具体怎么开、怎么调音量”。两边各忙各的。

新遥控器不用复制设备代码

想加静音键,只扩展遥控器:

public class MuteRemoteControl extends RemoteControl {
    public MuteRemoteControl(Device device) {
        super(device);
    }

    public void mute() {
        device.setVolume(0);
    }
}

这个静音遥控器既能配电视,也能配音响。

一款遥控器可以搭配不同设备

Device tv = new Tv();
RemoteControl remote = new RemoteControl(tv);
remote.togglePower();
remote.volumeUp();

Device speaker = new Speaker();
MuteRemoteControl muteRemote = new MuteRemoteControl(speaker);
muteRemote.togglePower();
muteRemote.mute();

输出:

电视开启=true, 音量=20
音响开启=true, 音量=0

桥接和适配器别混了

上一篇适配器模式,是两套已有接口对不上,中间加转换。

桥接模式通常在设计时就把两个变化方向拆开,让它们能分别扩展。

桥接模式与适配器模式的区别

适配器更像解决“接不上”;桥接更像提前避免“绑太死”。

这俩长得有点像,但出发点不一样。

啥时候适合用桥接

如果一个类只有一个变化方向,普通继承已经够用,没必要多拆一层。

当业务里能清楚看见两条独立变化线,而且两边还要自由组合,桥接模式才有价值。

什么时候适合使用桥接模式

像遥控器和设备、消息类型和发送渠道、图形和绘制方式,都能用这个思路理解。

先把两边分清,再用接口连起来。别一上来就造一堆抽象类,容易把自己绕进去。

狗哥收个尾

桥接模式最关键的地方,是 把两个变化方向拆开。

遥控器可以增加新功能,设备可以增加新类型。RemoteControl 持有 Device,两边通过组合配合,不用为每个组合再写一个类。

下一篇继续聊 组合模式,看看文件夹和文件这种树形结构怎么统一处理。


评论