前言:

  在我们还没学习框架之前,肯定都学过JDBC。百度百科对JDBC是这样介绍的【JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序,同时,JDBC也是个商标名。】通过JDBC我们可以完成Java对关系型数据库的SQL操作。下面我们介绍的这种模式是JDBC中使用的设计模式。

一、定义

  将抽象部分与它的具体实现部分分离,使他们都可以独立地变化。是通过组合方式建立两个类之间的联系,而不是继承

二、适用场景

1、抽象和具体实现之间增加更多灵活性

  使用桥接模式可以避免在这两个之间建立静态的继承关系,而是去建立组合关系。

2、一个类存在两个(或多个)独立变化的维度,且这两个维度需要独立进行扩展

  对于桥接模式可以这样理解,桥接就像一座桥,可以用来连接两个不同地方,这两个地方自由发展,中间的贸易是通过一座桥来连接。

3、不希望使用继承,或者是由于多层继承导致系统类的个数剧增

  同第一点理解

三、JDBC中的桥接模式

  首先我们弄清楚桥接模式中需要什么角色:

  1、实现类接口

  2、抽象类

  3、实现接口类

  4、继承抽象类

我们来看一下大概的图是怎么样的

  从图中我们能很清楚的看到抽象类和接口之间是通过组合方式来关联,这样关联有什么好处呢?抽象类下面可以自行发展自己的子类,并且接口类也可以自己发展子类。两者之间互不影响。这正是我们上面所说的两个维度独立扩展。不要以为客户端只能调用使用抽象类,而是接口下面的实现类可以放入抽象类的子类中进行操作。大致了解完之后,JDBC中又是怎么实现桥接模式的呢?

  我们对Driver接口一定不陌生。如果从桥接模式来看,Driver就是一个接口,下面可以有MySQL的Driver,Oracle的Driver,这些就可以当做实现接口类。那么我们现在来看看MySQL中的Driver类

public class Driver extends NonRegisteringDriver implements java.sql.Driver {
public Driver() throws SQLException {
} static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
}

特别简短的代码,其实只调用了DriverManager中的registerDriver方法来注册驱动。当驱动注册完成后,我们就会开始调用DriverManager中的getConnection方法了

public class DriverManager {
public static Connection getConnection(String url,
String user, String password) throws SQLException {
java.util.Properties info = new java.util.Properties(); if (user != null) {
info.put("user", user);
}
if (password != null) {
info.put("password", password);
} return (getConnection(url, info, Reflection.getCallerClass()));
} private static Connection getConnection(
String url, java.util.Properties info, Class<?> caller) throws SQLException {
/*
* When callerCl is null, we should check the application's
* (which is invoking this class indirectly)
* classloader, so that the JDBC driver class outside rt.jar
* can be loaded from here.
*/
ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
synchronized(DriverManager.class) {
// synchronize loading of the correct classloader.
if (callerCL == null) {
callerCL = Thread.currentThread().getContextClassLoader();
}
} if(url == null) {
throw new SQLException("The url cannot be null", "08001");
} println("DriverManager.getConnection(\"" + url + "\")"); // Walk through the loaded registeredDrivers attempting to make a connection.
// Remember the first exception that gets raised so we can reraise it.
SQLException reason = null; for(DriverInfo aDriver : registeredDrivers) {
// If the caller does not have permission to load the driver then
// skip it.
if(isDriverAllowed(aDriver.driver, callerCL)) {
try {
println(" trying " + aDriver.driver.getClass().getName());
Connection con = aDriver.driver.connect(url, info);
if (con != null) {
// Success!
println("getConnection returning " + aDriver.driver.getClass().getName());
return (con);
}
} catch (SQLException ex) {
if (reason == null) {
reason = ex;
}
} } else {
println(" skipping: " + aDriver.getClass().getName());
} } // if we got here nobody could connect.
if (reason != null) {
println("getConnection failed: " + reason);
throw reason;
} println("getConnection: no suitable driver found for "+ url);
throw new SQLException("No suitable driver found for "+ url, "08001");
} }
}

  上面是简化的代码,可以看到需要返回的是Connection对象。在Java中通过Connection提供给各个数据库一样的操作接口,这里的Connection可以看作抽象类。可以说我们用来操作不同数据库的方法都是相同的,不过MySQL有自己的ConnectionImpl类,同样Oracle也有对应的实现类。这里Driver和Connection之间是通过DriverManager类进行桥接的,不是像我们上面说的那样用组合关系来进行桥接。

四、总结

  桥接模式其实特别好理解,只需要看一眼上面的UML类图,也许你就知道桥接模式的使用方法。JDBC这里使用桥接模式可以让Driver和Connection下面的类根据不同数据库来实现不同的发展。就像我们适用场景中的第二点。当然正如我们标题所说的结合着JDK源码来看设计模式。也许看完这篇博客你有自己的理解JDBC这里为什么要用桥接模式。

结合JDK源码看设计模式——桥接模式的更多相关文章

  1. 结合JDK源码看设计模式——原型模式

    定义: 指原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.不需要知道任何创建的细节,不调用构造函数适用场景: 类初始化的时候消耗较多资源 new产生的对象需要非常繁琐的过程 构造函数比较 ...

  2. 结合JDK源码看设计模式——模板方法模式

    前言: 相信很多人都听过一个问题:把大象关进冰箱门,需要几步? 第一,把冰箱门打开:第二,把大象放进去:第三,把冰箱门关上.我们可以看见,这个问题的答案回答的很有步骤.接下来我们介绍一种设计模式--模 ...

  3. 结合JDK源码看设计模式——迭代器模式

    前言: Iterator翻译过来就是迭代器的意思.在前面的工厂模式中就介绍过了iterator,不过当时介绍的是方法,现在从Iterator接口的设计来看,似乎又是一种设计模式,下面我们就来讲讲迭代器 ...

  4. 结合JDK源码看设计模式——建造者模式

    概念: 将一个复杂对象的构建与它的表示分离.使得同样构建过程可以创建不同表示适用场景: 一个对象有很多属性的情况下 想把复杂的对象创建和使用分离 优点: 封装性好,扩展性好 详解: 工厂模式注重把这个 ...

  5. 结合JDK源码看设计模式——策略模式

    前言: 现在电商已经成为我们生活中不可或缺的购物渠道,同时各大商家会针对不同的时间做出不同的折扣,这在我们看来就是一种营销手段,也是一种策略,今天我们就来讲讲JDK中的策略模式是怎么样的. 一.定义 ...

  6. 结合JDK源码看设计模式——组合模式

    前言: 相信大家都打开过层级很多很多的文件夹.如果把第一个文件夹看作是树的根节点的话,下面的子文件夹就可以看作一个子节点.不过最终我们寻找的还是文件夹中的文件,文件可以看做是叶子节点.下面我们介绍一种 ...

  7. 结合JDK源码看设计模式——单例模式

    定义: 保证一个类仅有一个实例,并提供一个全局访问点 适用场景: 确保任何情况下这个对象只有一个实例 详解: 私有构造器 单利模式中的线程安全+延时加载 序列化和反序列化安全, 防止反射攻击 结合JD ...

  8. 结合JDK源码看设计模式——简单工厂、工厂方法、抽象工厂

    三种工厂模式的详解: 简单工厂模式: 适用场景:工厂类负责创建的对象较少,客户端只关心传入工厂类的参数,对于如何创建对象的逻辑不关心 缺点:如果要新加产品,就需要修改工厂类的判断逻辑,违背软件设计中的 ...

  9. 结合JDK源码看设计模式——享元模式

    前言 在说享元模式之前,你一定见到过这样的面试题 public class Test { public static void main(String[] args) { Integer a=Inte ...

随机推荐

  1. 基于ASP.NET MVC 微信网页登录授权(scope为snsapi_base) 流程 上 获取OPENID

    流程图 我们需要判断是否存在OPENID  首先我们得先定义一个全局的OPENID 类似于普通账号密码登录系统的 当前登录用户ID  因为我是MVC 框架  我这里定义一个控制器基类 BaseCont ...

  2. 利用JavaScriptSerializer转json实用方法

    项目中经常碰到需要输出的是json数据,使用JavaScriptSerializer转换,以前老的方法如下. JavaScriptSerializer jss = new JavaScriptSeri ...

  3. shell 中test命令

    test可用于测试表达式,支持测试的范围包括:字符串比较,算术比较,文件存在性.属性.类型等判断.例如,判断文件是否为空.文件是否存在.是否是目录.变量是否大于5.字符串是否等于"longs ...

  4. SSM-Spring-10:Spring中cglib动态代理

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 何为动态代理,就不扯皮了,上一篇博客刚刚提到,那cglib动态代理又怎么写,我拿个和上个例子相似的案例来写 具 ...

  5. Using INSERT IGNORE with MySQL to prevent duplicate key errors

    An error will occur when inserting a new record in MySQL if the primary key specified in the insert ...

  6. Ambiguous mapping found

    If you have a single default method (without explicit path mapping), then all requests without a mor ...

  7. 2. Java面向对象之泛型-构造方法中使用

    package generic; class Construtgeneric<T> { private T value; public Construtgeneric(T value) { ...

  8. 巩固java(三)---java修饰符

    正文:               下面的表格列出了java中修饰符的一些信息: 修饰符名称 类型 类 变量 方法 abstract 非访问控制符 抽象类          -- 抽象方法 final ...

  9. Java 学习笔记 (六) Java 定义变量

    这个问题来自于head first一书page68. package com.idea.study; public class Books { //headfirst page68 String ti ...

  10. 电脑开机失败提示"用户配置文件服务登录失败"的三种解决办法

    最近遇到这样一个怪现象,就是每次打开电脑输入密码,突然提示"User Profile Service 服务未能登录,无法加载用户配置文件",然后就没办法正常开机了,为什么会这样呢? ...