结合JDK源码看设计模式——桥接模式
前言:
在我們還沒學習框架之前,肯定都學過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這里為什么要用橋接模式。
?
轉載于:https://www.cnblogs.com/Cubemen/p/10678692.html
總結
以上是生活随笔為你收集整理的结合JDK源码看设计模式——桥接模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: selenium自动加载Flash
- 下一篇: TYVJ P2032 「Poetize9