Java设计模式——桥接模式

⚪桥接模式(Bridge)是一种结构型设计模式,这种模式的主要目的是将抽象和实现解耦,以便它们可以独立地扩展。

⚪意图:它将一个对象的抽象部分和它的实现部分分离,使它们可以独立地变化。

⚪以下是工厂方法模式的关键要点:

        ▷ 角色和责任

  1. 抽象(Abstraction):定义抽象类并包含一个指向实现对象的引用。它维护一个抽象部分的引用,并定义了需要委托给实现对象的接口。
  2. 扩充抽象(Refined Abstraction):扩展抽象类,并增加对抽象部分的额外功能。它可以是抽象类的子类。
  3. 实现(Implementor):定义实现类接口,这些接口将被具体的实现类实现。它不一定和抽象类具有完全相同的接口。实现对象负责实现抽象部分的接口。
  4. 具体实现(Concrete Implementor):提供实现类的具体实现。这些类实现了实现接口,以便抽象类可以委托给它们来执行实际的工作。

        ▷ 工作流程

  1. 抽象类定义了一组抽象方法,这些方法将由扩充抽象类使用,以完成其功能。
  2. 扩充抽象类继承了抽象类,并可以根据需要添加额外的方法或功能。它将抽象部分的操作委托给实现对象。
  3. 实现类实现了实现接口,提供了实现部分的具体实现。
  4. 在客户端代码中,抽象类和实现类之间的关联关系由抽象类的引用持有实现类的引用来表示。客户端通过抽象类来调用实际的实现。

        ▷ 示例

// 实现
interface Device {
    void turnOn();
    void turnOff();
    void setChannel(int channel);
}

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

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

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

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

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

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

// 抽象
abstract class RemoteControl {
    protected Device device;

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

    public abstract void powerOn();
    public abstract void powerOff();
    public abstract void setChannel(int channel);
}

// 扩充抽象
class BasicRemoteControl extends RemoteControl {
    public BasicRemoteControl(Device device) {
        super(device);
    }

    @Override
    public void powerOn() {
        System.out.println("Basic Remote: Power On");
        device.turnOn();
    }

    @Override
    public void powerOff() {
        System.out.println("Basic Remote: Power Off");
        device.turnOff();
    }

    @Override
    public void setChannel(int channel) {
        System.out.println("Basic Remote: Set Channel");
        device.setChannel(channel);
    }
}

public class BridgePatternExample {
    public static void main(String[] args) {
        Device tv = new TV();
        RemoteControl basicRemote = new BasicRemoteControl(tv);

        basicRemote.powerOn();
        basicRemote.setChannel(5);
        basicRemote.powerOff();
    }
}

⚪适用性

  1. 不希望在抽象和它的实现部分之间有一个固定的绑定关系。例如,这种情况可能是因为,在程序运行时刻实现部分应可以被选择或者切换。
  2. 类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。这是 Bridge 模式使得开发者可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充。
  3. 对一个抽象的实现部分的修改应对客户不产生影响,即客户代码不必重新编译。
  4. ( C ++)想对客户完全隐藏抽象的实现部分。
  5. ·有许多类要生成的类层次结构。
  6. ·想在多个对象间共享实现(可能使用引用计数),但同时要求客户并不知道这一点。

⚪应用场景

  1. 当你需要在抽象和实现之间引入一个稳定的接口,但又希望它们能够独立地变化时。 这是桥接模式的核心应用场景。例如,你可能有多个不同类型的遥控器(抽象部分),同时也有多个不同类型的设备(实现部分),并且你希望能够自由组合它们,而不需要创建每一个遥控器和设备之间的所有组合。
  2. 当一个类存在多个维度的变化,且希望避免类爆炸问题时。 使用继承来处理多维度变化可能导致类的指数级增长,而桥接模式可以将这些维度分离,使得管理更加容易。

⚪实际已有场景

  1. AWT(Abstract Window Toolkit)中的图形界面组件: AWT 使用了桥接模式,它允许你选择不同的窗口系统来运行 Java 程序,同时不改变应用程序的代码。
  2. JDBC 驱动程序: JDBC 驱动程序提供了一个抽象的接口来连接不同类型的数据库,而具体的数据库驱动程序则是实现这个接口的具体实现。
  3. Java 中的 I/O 类: Java 中的输入输出类库(如 InputStream 和 OutputStream)使用了桥接模式。它们提供了一个稳定的接口,而不同类型的数据源(文件、网络流、内存等)则是实现这一接口的具体实现。
  4. Spring JDBC: Spring 的 JDBC 模块使用桥接模式来支持不同类型的数据库连接池,例如 C3P0、HikariCP、Apache DBCP 等。这使得你可以轻松地切换和配置不同的数据库连接池,而不需要改变你的应用程序代码。
  5. Spring 的 Bean 容器: Spring 的 Bean 容器使用了桥接模式来支持不同的依赖注入方式,例如基于 XML 的配置、注解驱动的配置、JavaConfig 等。这使得你可以根据项目需求选择适当的配置方式,而不需要改变业务逻辑。
posted @ 2023-10-04 00:34  xiaogh  阅读(143)  评论(0)    收藏  举报