桥接模式是软件设计模式中最复杂的模式之一,它把事物对象和其具体行为、具体特征分离开来,使它们可以各自独立的变化。桥接模式的用意是将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立变化。这句话有3个关键词,也就是抽象化、实现化和脱耦。
将两个角色之间的继承关系改为聚合关系,就是将它们之间的强关联转换成为弱关联。因此,桥接模式中的所谓脱耦,就是指在一个软件系统的抽象化和实现化之间使用组合/聚合关系而不是继承关系,从而使两者可以相对独立变化,这就是桥接模式的用意。
桥接模式所涉及的角色如下。
如下图所示就是一个实现了桥接模式的示意性系统的结构图。

图中的 Client就可以通过 Bridge桥来实现对 Sourcable 实现类的操作了。
下面来看具体的实现。
(1) Sourcable 类的源代码如下程序所示,它定义了两个操作函数。
源接口 Sourcable.java
package structure.adapter;
/**
* @author Minggg
* 源接口
*/
public interface Sourcable {
public void operation();
}
(2) SourceSub1实现了Sourcable接口,实现函数operation()负责输出一个字符串。其源代码如下程序所示。
源接口的实现子类SourceSub1.java
package structure.adapter;
/**
* @author Minggg
* 源接口的实现类
*/
public class SourceSub1 extends DefaultWrapper {
public void operation() {
System.out.printIn("源接口的一个实现子类 Sub1");
}
}
(3) SourceSub2实现了 Sourcable 接口,实现函数 operation()负责输出一个字符串。其源代码如下程序 所示。
源接口的实现子类SourceSub2.java
package structure.adapter;
/**
* @author Minggg
* 源接口的实现类
*/
public class SourceSub2 extends DefaultWrapper {
public void operation() {
System.out.printIn("源接口的一个实现子类 Sub2");
}
}
(4) 桥接类 Bridge是一个抽象类,它拥有一个 Sourcable 对象,并可以通过 getter/setter 来设置该对象。其源代码如下程序所示。
桥接类 Bridge.java
package structure.adapter;
/**
* @author Minggg
* 桥接类
*/
public abstract class Bridge {
private Sourcable source;
public Sourcable getSource() {
return source;
}
public void setSource(Sourcable source){
this.source = source;
}
public void operation() {
source.operation();
}
}
(5) 桥接具体类MyBridge是一个Bridge的具体实现,它拥有自己的实现。其源代码如下程序所示。
桥接具体类 MyBridge.java
package structure.adapter;
/**
* @author Minggg
* 桥接具体类
*/
public class MyBridge extends Bridge {
public void operation() {
getSource().operation();
}
}
以上我们编写了两个实现 SourceSub1和 SourceSub2,下面我们便可以通过 Bridge 桥来实现对它们的调用。首先创建一个桥对象,然后分别给该桥设置不同的目标对象source1和source2,然后调用桥的 operation()即可实现对两个目标的调用。其源代码如下程序所示。
测试类 Client,java
package structure.adapter;
public class Client {
public static void main(String[] args) {
// 创建桥对象
Bridge bridge = new MyBridge();
// 调用第一个对象
Sourcable source1 = new SourceSub1();
bridge.setSource(source1);
bridge.operation();
// 调用第二个对象
Sourcable source2 = new SourceSub2();
bridge.setSource(source2);
bridge.operation();
}
}
运行该程序的结果如下:
源接口的一个实现子类 Sub1
源接口的一个实现子类 Sub2
从输出的结果可以看出,通过 Bridge桥实现了对目标类的调用。
从以上的讲解可以看出,桥接模式与前面几种模式都很相似,但是它们应用的目的和场景不同:
由此可见,桥接模式与前面几种模式都很相似,这是应用的角度不同。它只有在一个系统中拥有更多的抽象化和实现化角色时才使用,目的是为了增加互相操作的灵活性。
桥接模式的关键是找出抽象化角色和具体化角色。典型应用是JDBC应用,IDBCAPI属于抽象化角色,而 driver 则属于具体化角色,其中需要通过一个 DriverManager 类根据指定 URL,得到具体实现。
如图下所示,DriverManager 就为我们提供了一个桥,通过这个桥可以实现对各种数据库驱动的加载。

因为有了 DriverManager 桥,我们才可以像下面这样方便地连接各种数据源。
Class.forName( "org.git.mm.mysql.Driver");
cn = DriverManager.getConnection( "jdbc:mysgl://DBServerlP:3306/myDatabaseName", sUsr, sPwd );
Class.forName( "oracle.jdbc driver.OracleDriver");
cn = DriverManager.getConnection( "jdbc:oracle:thin:@MyDbComputerNameOrIP:1521ORCL", sUsr, sPwd );
…另外其他各种数据库连接就不一一展示了