【源碼分析設計模式 12】JDBC中的橋接模式

一、基本介紹

將實現與抽象放在兩個不同的層次中,使兩個層次可以獨立改變。

橋接模式基於類的最小設計原則,通過使用封裝、聚合、繼承等行爲讓不同的類承擔不同的職責。

它的主要特點是把抽象與行爲實現分離開,從而可以保持各部分的獨立性以及功能擴展。

二、橋接模式的結構

 其中,Abstraction爲抽象化角色,定義出該角色的行爲,同時保存一個對實現化角色的引用;Implementor是實現化角色,它是接口或者抽象類,定義角色必需的行爲和屬性;RefinedAbstraction爲修正抽象化角色,引用實現化角色對抽象化角色進行修正;ConcreteImplementor爲具體實現化角色,實現接口或抽象類定義的方法或屬性。

三、橋接模式的優缺點

1、優點

(1)實現了抽象和實現部分的分離

橋接模式分離了抽象部分和實現部分,從而極大的提供了系統的靈活性,讓抽象部分和實現部分獨立開來,分別定義接口,這有助於系統進行分層設計,從而產生更好的結構化系統。對於系統的高層部分,只需要知道抽象部分和實現部分的接口就可以了。

(2)更好的可擴展性

由於橋接模式把抽象部分和實現部分分離了,從而分別定義接口,這就使得抽象部分和實現部分可以分別獨立擴展,而不會相互影響,大大的提供了系統的可擴展性。

(3)可動態的切換實現

由於橋接模式實現了抽象和實現的分離,所以在實現橋接模式時,就可以實現動態的選擇和使用具體的實現。

(4)實現細節對客戶端透明,可以對用戶隱藏實現細節。

2、缺點

(1)橋接模式的引入增加了系統的理解和設計難度,由於聚合關聯關係建立在抽象層,要求開發者針對抽象進行設計和編程。

(2)橋接模式要求正確識別出系統中兩個獨立變化的維度,因此其使用範圍有一定的侷限性。

四、橋接模式的應用場景

1、不希望或不適用使用繼承的場景

2、接口或抽象類不穩定的場景

3、重用性要求較高的場景

應用實例:

(1)開關。我們可以看到的開關是抽象的,不用管裏面具體怎麼實現;

(2)手機品牌與手機軟件。兩者間有一條聚合線,一個手機品牌可以有多個手機軟件。

不要一涉及繼承就考慮該模式,儘可能把變化的因素封裝到最細、最小的邏輯單元中,避免風險擴散。

當發現類的繼承有n層時,可以考慮使用該模式。

五、代碼實現

1、品牌

package designMode.advance.bridge;

public interface Brand {
    void open();
    void close();
    void call();
}

2、具體品牌

package designMode.advance.bridge;

public class Vivo implements Brand {
    @Override
    public void open() {
        System.out.println(" Vivo手機開機 ");
    }

    @Override
    public void close() {
        System.out.println(" Vivo手機關機 ");
    }

    @Override
    public void call() {
        System.out.println(" Vivo手機打電話 ");
    }
}
package designMode.advance.bridge;

public class XiaoMi implements Brand {
    @Override
    public void open() {
        System.out.println(" 小米手機開機 ");
    }

    @Override
    public void close() {
        System.out.println(" 小米手機關機 ");
    }

    @Override
    public void call() {
        System.out.println(" 小米手機打電話 ");
    }
}

3、手機樣式,行爲類

package designMode.advance.bridge;

public abstract class Phone {
    //組合品牌
    private Brand brand;

    //構造器
    public Phone(Brand brand) {
        super();
        this.brand = brand;
    }

    protected void open() {
        this.brand.open();
    }
    protected void close() {
        brand.close();
    }
    protected void call() {
        brand.call();
    }
}
package designMode.advance.bridge;

public class UpRightPhone extends Phone {
    //構造器
    public UpRightPhone(Brand brand) {
        super(brand);
    }

    public void open() {
        super.open();
        System.out.println(" 直立樣式手機 ");
    }

    public void close() {
        super.close();
        System.out.println(" 直立樣式手機 ");
    }

    public void call() {
        super.call();
        System.out.println(" 直立樣式手機 ");
    }
}
package designMode.advance.bridge;

public class FoldedPhone extends Phone  {
    //構造器
    public FoldedPhone(Brand brand) {
        super(brand);
    }

    public void open() {
        super.open();
        System.out.println(" 摺疊樣式手機 ");
    }

    public void close() {
        super.close();
        System.out.println(" 摺疊樣式手機 ");
    }

    public void call() {
        super.call();
        System.out.println(" 摺疊樣式手機 ");
    }
}

4、測試類

package designMode.advance.bridge;

public class Client {
    public static void main(String[] args) {
        //獲取摺疊式手機 (樣式 + 品牌 )
        Phone phone1 = new FoldedPhone(new XiaoMi());
        phone1.open();
        phone1.call();
        phone1.close();

        System.out.println("=======================");

        Phone phone2 = new FoldedPhone(new Vivo());

        phone2.open();
        phone2.call();
        phone2.close();

        System.out.println("==============");

        UpRightPhone phone3 = new UpRightPhone(new XiaoMi());

        phone3.open();
        phone3.call();
        phone3.close();

        System.out.println("==============");

        UpRightPhone phone4 = new UpRightPhone(new Vivo());

        phone4.open();
        phone4.call();
        phone4.close();
    }
}

5、控制檯輸出

六、JDBC中的橋接模式

使用JCBC的時候,一直很困惑獲取connection的過程和原理,爲什麼把不同的數據庫驅動名稱放到Class.forName()中就能獲取到對應的數據庫連接呢?

Oracle爲例,通過Class.forName("oracle.jdbc.OracleDriver")類加載的時候執行靜態代碼塊將Driver註冊到DriverManager,DriverManager是個Driver容器,管理不同的Driver,這樣具體的數據Driver實現就統一交給容器管理,客戶端通過DriverManager執行驗證連接,獲取連接的操作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章