溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

java橋接模式的介紹以及模式的結(jié)構(gòu)

發(fā)布時(shí)間:2021-09-04 10:32:36 來源:億速云 閱讀:180 作者:chen 欄目:大數(shù)據(jù)

本篇內(nèi)容介紹了“java橋接模式的介紹以及模式的結(jié)構(gòu)”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

橋接模式(Bridge Pattern):將抽象部分與它的實(shí)現(xiàn)部分分離,使它們都可以獨(dú)立地變化。它是一種對象結(jié)構(gòu)型模式,又稱為柄體(Handle and Body)模式或接口(Interface)模式。

設(shè)想如果要繪制矩形、圓形、橢圓、正方形,我們至少需要4個(gè)形狀類,但是如果繪制的圖形需要具有不同的顏色,如紅色、綠色、藍(lán)色等,此時(shí)至少有如下兩種設(shè)計(jì)方案:

  1. 為每一種形狀都提供一套各種顏色的版本。

  2. 根據(jù)實(shí)際需要對形狀和顏色進(jìn)行組合

對于有兩個(gè)變化維度(即兩個(gè)變化的原因)的系統(tǒng),采用第二種方案來進(jìn)行設(shè)計(jì)系統(tǒng)中類的個(gè)數(shù)更少,且系統(tǒng)擴(kuò)展更為方便。第二種方案即是橋接模式的應(yīng)用。橋接模式將繼承關(guān)系轉(zhuǎn)換為關(guān)聯(lián)關(guān)系,從而降低了類與類之間的耦合,減少了代碼編寫量。對于有兩個(gè)變化維度(即兩個(gè)變化的原因)的系統(tǒng),采用橋接模式開發(fā)更為方便簡潔。橋接模式將繼承關(guān)系轉(zhuǎn)換為關(guān)聯(lián)關(guān)系,從而降低了類與類之間的耦合,減少了代碼編寫量。

<!--more-->

模式結(jié)構(gòu)

橋接模式包含如下角色:

  • Abstraction:抽象類,橋接類

  • RefinedAbstraction:擴(kuò)充抽象類

  • Implementor:實(shí)現(xiàn)類,被橋接的接口

  • ConcreteImplementor:具體實(shí)現(xiàn)類

源碼導(dǎo)讀

JDBC是基于Java支持多種數(shù)據(jù)庫的操作,但是不同數(shù)據(jù)庫的自我實(shí)現(xiàn)和傳輸協(xié)議都不盡相同,難道Java為每一種數(shù)據(jù)庫寫一種接口去支持?jǐn)?shù)據(jù)庫廠商的實(shí)現(xiàn),顯然違背了精簡設(shè)計(jì)的原則,這里Java做的是提供一套接口讓廠商自己實(shí)現(xiàn),一套接口給程序開發(fā)者調(diào)用,兩者的結(jié)合就是經(jīng)典的橋接模式。作為程序員操作jdbc是這樣的:

    Class.forName("com.mysql.jdbc.Driver");
    String url = "";
    String user = "";
    String password = "";
    Connection con = DriverManager.getConnection(url, user, password);
    Statement statement = connection.createStatement();
    String sql = "insert into student (name,age) VALUE ('" + name + "'," + age + ")";
    statement.execute(sql);

我們來看看``部分源碼

 private static Connection getConnection(String var0, Properties var1, Class<?> var2) throws SQLException {
        ClassLoader var3 = var2 != null ? var2.getClassLoader() : null;
        Class var4 = DriverManager.class;
        synchronized(DriverManager.class) {
            if (var3 == null) {
                var3 = Thread.currentThread().getContextClassLoader();
            }
        }

        if (var0 == null) {
            throw new SQLException("The url cannot be null", "08001");
        } else {
            println("DriverManager.getConnection(\"" + var0 + "\")");
            SQLException var10 = null;
            Iterator var5 = registeredDrivers.iterator();

            while(true) {
                while(var5.hasNext()) {
                    DriverInfo var6 = (DriverInfo)var5.next();
                    if (isDriverAllowed(var6.driver, var3)) {
                        try {
                            println("    trying " + var6.driver.getClass().getName());
                            Connection var7 = var6.driver.connect(var0, var1);
                            if (var7 != null) {
                                println("getConnection returning " + var6.driver.getClass().getName());
                                return var7;
                            }
                        } catch (SQLException var8) {
                            if (var10 == null) {
                                var10 = var8;
                            }
                        }
                    } else {
                        println("    skipping: " + var6.getClass().getName());
                    }
                }

                if (var10 != null) {
                    println("getConnection failed: " + var10);
                    throw var10;
                }

                println("getConnection: no suitable driver found for " + var0);
                throw new SQLException("No suitable driver found for " + var0, "08001");
            }
        }
    }

看這幾行代碼

 ClassLoader var3 = var2 != null ? var2.getClassLoader() : null;
        Class var4 = DriverManager.class;
        synchronized(DriverManager.class) {
            if (var3 == null) {
                var3 = Thread.currentThread().getContextClassLoader();
            }
        }
	 ......
     ......
Connection var7 = var6.driver.connect(var0, var1);

其實(shí)這里DriverManager獲得Connection是通過反射和類加載機(jī)制從數(shù)據(jù)庫驅(qū)動(dòng)包的driver中拿到連接,所以這里真正參與橋接模式的是driver,而DriverManager和橋接模式?jīng)]有關(guān)系,DriverManager只是對driver的一個(gè)管理器。而我們作為使用者只去關(guān)心Connection,不會(huì)去關(guān)心driver,因?yàn)槲覀兊牟僮鞫际峭ㄟ^操作Connection來實(shí)現(xiàn)的。這樣分析下來這個(gè)橋接就清晰了邏輯——java.sql.Driver作為抽象橋類,而驅(qū)動(dòng)包如com.mysql.jdbc.Driver具體的實(shí)現(xiàn)橋接類,而Connection是被橋接的對象。這里的兩個(gè)維度是:

  • 數(shù)據(jù)庫類型的不同(驅(qū)動(dòng)不同)

  • 數(shù)據(jù)庫的連接信息不同(URL,username,password)

現(xiàn)在假設(shè)一個(gè)這樣的場景-我們設(shè)計(jì)了一個(gè)框架,需要對外提供api,但是這個(gè)框架內(nèi)部某個(gè)類需要頻繁變更,很不穩(wěn)定,但是我們提供的api不能一直變吧。如何將api的方法和頻繁變更的代碼隔離開呢,其實(shí)就可以考慮適配器模式或者橋接模式。

“java橋接模式的介紹以及模式的結(jié)構(gòu)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI