定义

GoF 《设计模式》的解释:

Decouple an abstraction from its implementation so that the two can vary independently 将抽象和实现解耦,让它们可以独立变化。

结构

  1. 抽象化(Abstraction)角色:定义抽象类,并包含一个对实现化对象的引用。
  2. 扩展抽象化(Refined Abstraction)角色:是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。
  3. 实现化(Implementor)角色:定义实现化角色的接口,供扩展抽象化角色调用。
  4. 具体实现化(Concrete Implementor)角色:给出实现化角色接口的具体实现。

桥接模式(Bridge Pattern) - 图1

应用

JDBC

不同的数据库驱动,共用同一套JDBC规范,即同一套接口,如Connection,Statement,ResultSet等。

  1. Class.forName("com.mysql.jdbc.Driver");
  2. Class.forName("oracle.jdbc.driver.OracleDriver");

Class.forName首先会要求JVM查找并加载指定Driver类,并执行该类的静态代码。相关的静态代码如下,目的就是将 MySQL/Oracle Driver 注册到 DriverManager 类中。

  1. package com.mysql.jdbc;
  2. import java.sql.SQLException;
  3. public class Driver extends NonRegisteringDriver implements java.sql.Driver {
  4. static {
  5. try {
  6. java.sql.DriverManager.registerDriver(new Driver());
  7. } catch (SQLException E) {
  8. throw new RuntimeException("Can't register driver!");
  9. }
  10. }
  11. /**
  12. * Construct a new driver and register it with DriverManager
  13. * @throws SQLException if a database error occurs.
  14. */
  15. public Driver() throws SQLException {
  16. // Required for Class.forName().newInstance()
  17. }
  18. }

注册到 DriverManager 之后,后续所有对 JDBC 接口的调用,都会委派到对具体的 Driver 实现类来执行。而 Driver 实现类都实现了相同的接口(java.sql.Driver )。

  1. public class DriverManager {
  2. private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<DriverInfo>();
  3. //...
  4. static {
  5. loadInitialDrivers();
  6. println("JDBC DriverManager initialized");
  7. }
  8. //...
  9. public static synchronized void registerDriver(java.sql.Driver driver) throws SQLException {
  10. if (driver != null) {
  11. registeredDrivers.addIfAbsent(new DriverInfo(driver));
  12. } else {
  13. throw new NullPointerException();
  14. }
  15. }
  16. public static Connection getConnection(String url, String user, String password) throws SQLException {
  17. java.util.Properties info = new java.util.Properties();
  18. if (user != null) {
  19. info.put("user", user);
  20. }
  21. if (password != null) {
  22. info.put("password", password);
  23. }
  24. return (getConnection(url, info, Reflection.getCallerClass()));
  25. }
  26. //...
  27. }

对于这个例子,抽象指的是JDBC规范,是一系列JDBC接口。实现指的是MYSQL和ORACLE针对这些接口的实现。而抽象是由JDK开发团队负责开发,实现则由各自的数据库开发团队进行开发。