桥接模式的作用:将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。
案例
桥接模式比较经典的应用就是 JDBC 规范和不同数据库厂商驱动的实现
JDBC 中的驱动接口
public interface Driver {
Connection connect(String url, java.util.Properties info) throws SQLException;
boolean acceptsURL(String url) throws SQLException;
.
.
.
}
JDBC 中的驱动管理器
public class DriverManager {
private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<>();
private DriverManager(){}
public static synchronized void registerDriver(java.sql.Driver driver, DriverAction da) throws SQLException {
if(driver != null) {
registeredDrivers.addIfAbsent(new DriverInfo(driver, da));
} else {
throw new NullPointerException();
}
}
private static Connection getConnection( String url, java.util.Properties info, Class<?> caller) throws SQLException {
ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
synchronized(DriverManager.class) {
if (callerCL == null) {
callerCL = Thread.currentThread().getContextClassLoader();
}
}
if(url == null) {
throw new SQLException("The url cannot be null", "08001");
}
SQLException reason = null;
for(DriverInfo aDriver : registeredDrivers) {
if(isDriverAllowed(aDriver.driver, callerCL)) {
try {
Connection con = aDriver.driver.connect(url, info);
if (con != null) {
return (con);
}
} catch (SQLException ex) {
if (reason == null) {
reason = ex;
}
}
} else {
}
}
.
.
.
}
}
MySQL 的 Driver 继承的 NonRegisteringDriver 类
package com.mysql.jdbc;
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
//加载驱动的时候,自动注册到驱动管理器
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
public Driver() throws SQLException {
}
}
MySQL 的 NonRegisteringDriver 对 JDBC 中的 Driver 接口进行实现
public class NonRegisteringDriver implements java.sql.Driver {
private static final String ALLOWED_QUOTES = "\"'";
private static final String REPLICATION_URL_PREFIX = "jdbc:mysql:replication://";
private static final String URL_PREFIX = "jdbc:mysql://";
.
.
.
public java.sql.Connection connect(String url, Properties info) throws SQLException {
.
.
.
try {
Connection newConn = com.mysql.jdbc.ConnectionImpl.getInstance(host(props), port(props), props, database(props), url);
return newConn;
} catch (SQLException sqlEx) {
throw sqlEx;
} catch (Exception ex) {
SQLException sqlEx = SQLError.createSQLException(
Messages.getString("NonRegisteringDriver.17") + ex.toString() + Messages.getString("NonRegisteringDriver.18"),
SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE, null);
sqlEx.initCause(ex);
throw sqlEx;
}
}
}
示意图:
ConstXiong 备案号:苏ICP备16009629号-3