23 设计模式:桥接模式--结构型模式

135 阅读4分钟

结构型模式之:

  • 桥接模式
  • 适配器模式
  • 组合模式
  • 装饰模式
  • 外观模式
  • 代理模式
  • 享元模式

1.什么是桥接模式?

桥接模式是一种结构型设计模式,它将抽象部分与实现部分分离,使它们可以独立变化,而不会相互影响。桥接模式通过组合而不是继承的方式实现不同维度的变化,从而减少了类之间的耦合性。

image.png

(图是网上找的)

假设我们有一个远程控制器可以控制不同类型的设备,比如电视和音响。远程控制器可以有不同的遥控器按钮,比如开关按钮、调节音量按钮等。我们希望能够通过远程控制器来控制不同类型的设备,并且能够灵活地增加新的遥控器按钮。

// 实现部分接口:Device
public interface Device {
    void turnOn();
    void turnOff();
    void setVolume(int volume);
}

// 具体实现类:TV
public class TV implements Device {
    @Override
    public void turnOn() {
        System.out.println("TV is turned on");
    }

    @Override
    public void turnOff() {
        System.out.println("TV is turned off");
    }

    @Override
    public void setVolume(int volume) {
        System.out.println("TV volume is set to " + volume);
    }
}

// 具体实现类:音响类
public class Stereo implements Device {
    @Override
    public void turnOn() {
        System.out.println("Stereo is turned on");
    }

    @Override
    public void turnOff() {
        System.out.println("Stereo is turned off");
    }

    @Override
    public void setVolume(int volume) {
        System.out.println("Stereo volume is set to " + volume);
    }
}

下面是遥控器的抽象类和具体实现类


// 抽象部分接口:RemoteControl
public interface RemoteControl {
    void powerOn();
    void powerOff();
    void setVolume(int volume);
}

// 扩展抽象部分类:ConcreteRemoteControl(通过组合的方式,判断控制哪一种设备的开和关)
public class ConcreteRemoteControl implements RemoteControl {
    protected Device device;

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

    @Override
    public void powerOn() {
        device.turnOn();
    }

    @Override
    public void powerOff() {
        device.turnOff();
    }

    @Override
    public void setVolume(int volume) {
        device.setVolume(volume);
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Device tv = new TV();
        RemoteControl tvRemoteControl = new ConcreteRemoteControl(tv);

        Device stereo = new Stereo();
        RemoteControl stereoRemoteControl = new ConcreteRemoteControl(stereo);

        tvRemoteControl.powerOn();
        tvRemoteControl.setVolume(20);
        tvRemoteControl.powerOff();

        stereoRemoteControl.powerOn();
        stereoRemoteControl.setVolume(30);
        stereoRemoteControl.powerOff();
    }
}

在这个示例中,Device是实现部分接口,表示不同的设备,比如TV和Stereo。RemoteControl是抽象部分接口,表示遥控器。ConcreteRemoteControl是扩展抽象部分类,表示具体的遥控器。通过桥接模式,我们将遥控器和设备两个维度进行了分离,使得它们可以独立变化,更加灵活。

2. 什么情况下要使用桥接模式?

如果你想要拆分或重组一个具有多重功能的庞杂类 (例如能与多个数据库服务器进行交互的类), 可以使用桥接模式。

类的代码行数越多, 弄清其运作方式就越困难, 对其进行修改所花费的时间就越长。 一个功能上的变化可能需要在整个类范围内进行修改, 而且常常会产生错误, 甚至还会有一些严重的副作用。

桥接模式可以将庞杂类拆分为几个类层次结构。 此后, 你可以修改任意一个类层次结构而不会影响到其他类层次结构。 这种方法可以简化代码的维护工作, 并将修改已有代码的风险降到最低。

当一个类存在多个独立变化的维度时,可以考虑使用桥接模式。 

例如,在上面的示例中,遥控器有多种按钮(开关按钮、调节音量按钮等),而每种按钮又可以控制不同的设备(TV、Stereo等),这就是两个独立变化的维度。

当需要在运行时动态地将实现部分替换为不同的实现时,桥接模式也是一个不错的选择 

当然并不是说一定要实现这一点, 桥接模式可替换抽象部分中的实现对象, 具体操作就和给成员变量赋新值一样简单。

3.桥接模式的优缺点

  • 你可以创建与平台无关的类和程序。
  • 客户端代码仅与高层抽象部分进行互动, 不会接触到平台的详细信息。
  • 开闭原则。 你可以新增抽象部分和实现部分, 且它们之间不会相互影响。
  • 单一职责原则。 抽象部分专注于处理高层逻辑, 实现部分处理平台细节。

实际中,桥接模式使用的较少,这里先专注于了解什么是桥接模式,以及桥接模式的优点缺点,特别是使用场景。