桥接模式(Bridge Pattern):结构型模式之一,将抽象与实现分离,使它们可以独立变化。
前言:举个栗子,我们的电脑因为安装了太多软件,没有内存空间了,于是我们可以对我们的电脑进行加装硬盘,我们把电脑拿到电脑城,发现技术小哥打开机箱后直接将硬盘插进了一个卡槽里,这时我们发现,加装硬盘如此方便,原来是之前就预留了接口,我们直接将需要的硬件插进这个接口里就可以实现动态扩展,而不需要修改整个主机。这就是设计模式之桥接模式。
计算机(抽象类 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硬盘
在我们刚开始接触的项目中,我们经常会使用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加载的类,如果把加载类的声明放入配置文件中,更是不需要重新去编译,可以很方便地在不同数据库间进行转化。
优点
缺点
如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。一个类存在两个独立变化的维度,且这两个维度都需要进行扩展,也可以适用桥接模式。
桥接模式分离了抽象部分和实现部分,从而极大地提高了系统的灵活性。让抽象部分和实现部分独立开来,分别定义接口,这有助于对系统进行分层,从而产生更好的结构化的系统。