桥接模式(Bridge Pattern)

一、定义

桥接模式(Bridge Pattern):结构型模式之一,将抽象与实现分离,使它们可以独立变化

二、UML类图

在这里插入图片描述

三、角色职责

  • 抽象类(Abstraction):定义抽象接口,由聚合关系可知,抽象类中包含一个Implementor类型的对象,它与Implementor之间有关联关系,既可以包含抽象业务方法,也可以包含具体业务方法。
  • 实现类接口(Implementor):定义实现类的接口,这个接口可以与Abstraction类的接口不同。一般而言,实现类接口只定义基本操作,而抽象类的接口还可能会做更多复杂的操作。
  • 扩充抽象类(RefinedAbstraction):具体类,实现在抽象类中定义的接口,可以调用在Implementor中定义的方法。
  • 具体实现类(ConcreteImplementor):具体实现了Implementor接口,在不同的具体实现类中实现不同的具体操作。运行时ConcreteImplementor将替换父类。

四、代码实现

前言:举个栗子,我们的电脑因为安装了太多软件,没有内存空间了,于是我们可以对我们的电脑进行加装硬盘,我们把电脑拿到电脑城,发现技术小哥打开机箱后直接将硬盘插进了一个卡槽里,这时我们发现,加装硬盘如此方便,原来是之前就预留了接口,我们直接将需要的硬件插进这个接口里就可以实现动态扩展,而不需要修改整个主机。这就是设计模式之桥接模式。

计算机(抽象类 Abstraction)

public abstract class Computer {
    protected HarddiskAPI harddiskAPI;

    public void setHarddiskAPI(HarddiskAPI harddiskAPI) {
        this.harddiskAPI = harddiskAPI;
    }

    public abstract void describe();
}

个人计算机(实现类接口 Implementor)

public class PCComputer extends Computer {
    @Override
    public void describe() {
        System.out.println("我是个人计算机");
        harddiskAPI.add();
    }
}

服务器(实现类接口 Implementor)

public class ServerComputer extends Computer {
    @Override
    public void describe() {
        System.out.println("我是服务器");
        harddiskAPI.add();
    }
}

硬盘(扩充抽象类 RefinedAbstraction)

public interface HarddiskAPI {
    void add();
}

512G硬盘(具体实现类 ConcreteImplementor)

public class Harddisk512GAPI implements HarddiskAPI {
    @Override
    public void add() {
        System.out.println("加装512G硬盘");
    }
}

1T硬盘(具体实现类 ConcreteImplementor)

public class Harddisk1TAPI implements HarddiskAPI {
    @Override
    public void add() {
        System.out.println("加装1T硬盘");
    }
}

测试类

public class BridgeTest {
    public static void main(String[] args) {
        Computer pc = new PCComputer();
        pc.setHarddiskAPI(new Harddisk512GAPI());
        pc.describe();

        Computer server = new ServerComputer();
        server.setHarddiskAPI(new Harddisk1TAPI());
        server.describe();
    }
}

输出结果

我是个人计算机
加装512G硬盘
我是服务器
加装1T硬盘

五、源码分析

![在这里插入图片描述](https://img-blog.csdnimg.cn/123be549160e4be69416220399a4287b.png)在Mybatis中的Configuration类里,就使用到了外观模式。我们只需要调用Configuration类的newMetaObject()方法,并传递一个Object类型参数,就可以得到MetaObject对象,客户端并不需要关心这个对象是如何生成的。我们点进Configuration类。![在这里插入图片描述](https://img-blog.csdnimg.cn/c832271be42c467bb3b8ede04b62e7a0.png)那MetaObject是如何产生的呢?我们点进forObject()方法。![在这里插入图片描述](https://img-blog.csdnimg.cn/806b5a8981e74c13b88d7588e7a89e26.png)可以看到,forObject会调用MetaObject的构造方法,然后根据你传入的对象类型去构建一个MetaObject对象并返回。这就是典型的外观模式。
在我们刚开始接触的项目中,我们经常会使用JDBC,而JDBC就是一个经典的桥接模式案例。JDBC进行连接数据库的时候,在各个数据库之间进行切换,基本不需要动太多的代码,甚至丝毫不用动,原因就是JDBC提供统一接口,每个数据库提供各自的实现,用一个叫做数据库驱动的程序来桥接就行了。运行程序时,JVM首先检查是否所要加载的类对应的Class对象已经加载。如果没有加载,JVM就会根据类名查找.class文件,并将其Class对象载入。每个数组被映射为Class对象的一个类,所有具有相同元素类型和维数的数组都能共享该Class对象。一般某个类的Class对象被载入内存,它就用来创建这个类的所有对象。在Class.forName加载完驱动类后,开始执行静态代码块时,会new一个Driver,并调用DriverManager的registerDriver把Driver给注册到自己的驱动程序管理器(DriverManager)中去。
在这里插入图片描述

JDBC的类族设计是由sum公司设计了一套接口,再由各个数据库公司实现接口,我们在调用的过程中只需要使用接口去定义,然后在加载Driver的过程中底层代码会给我们选择好接口真正的实现类,以此来实现真正的数据库连接。更换数据库就代表着更换驱动,而所有驱动都实现了这个接口,那我们只需要在利用反射加载驱动的class.forName()方法中注明需要加载的驱动就ok了,这样就可以适配所有的数据库。用这种桥接的模式,我们可以很轻松地在不同的数据库连接中进行转化,只需要修改Driver加载的类,如果把加载类的声明放入配置文件中,更是不需要重新去编译,可以很方便地在不同数据库间进行转化。

六、优缺点分析

优点

  • 桥接模式把抽象部分和实现部分分离了,从而分别定义接口,这就使得抽象部分和实现部分可以分别独立扩展,而不会相互影响。

缺点

  • 桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围有一定的局限性。

七、适用场景

如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。一个类存在两个独立变化的维度,且这两个维度都需要进行扩展,也可以适用桥接模式。

八、总结

桥接模式分离了抽象部分和实现部分,从而极大地提高了系统的灵活性。让抽象部分和实现部分独立开来,分别定义接口,这有助于对系统进行分层,从而产生更好的结构化的系统。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值