設計模式(八)橋接模式

版權聲明:轉載必須註明本文轉自曉_晨的博客:http://blog.csdn.net/niunai112

目錄

導航

設計模式之六大設計原則
設計模式(一)單例模式
設計模式(二)工廠模式
設計模式(三)策略模式
設計模式(四)適配器模式
設計模式(五)享元模式
設計模式(六)建造者模式
設計模式(七)原型模式
設計模式(八)橋接模式
設計模式(九)外觀模式
設計模式(十)組合模式
設計模式(十一)裝飾器模式
設計模式(十二)代理模式
設計模式(十三)迭代器模式
設計模式(十四)觀察者模式
設計模式(十五)中介者模式
設計模式(十六)命令模式
設計模式(十七)狀態模式
設計模式(十八)訪問者模式
設計模式(十九)責任鏈模式
設計模式(二十)解釋器模式
設計模式(二十一)備忘錄模式
設計模式(二十二)模板模式
設計模式總結篇(爲什麼要學習設計模式,學習設計模式的好處)

前言

LZ帶大家來學習一下橋接模式。在項目中經常會用到的模式,我們的JDBC驅動程序也是使用橋接模式,DriverManager中有Driver接口,各個數據庫廠商自己實現各自的Driver類,然後在使用的時候,我們只需要把這個Driver放進去就可以了。

橋接模式的目的是:分離抽象化和實現,使兩者的接口可以不同,目的是分離。

橋接模式的角色有:

實現(Implementor):定義具體行爲,具體特徵的應用接口。

具體實現(ConcreteImplementor):實現Implementor。

目標接口(Target): 包含實現具體行爲、具體特徵的Implementor接口或者類。

橋接模式通過在Target裏的操作,調用Implementor得操作,達到了Target的抽象與Implementor實現的分離。

例子

假如LZ是一個組配電腦的,目前只用配電腦的CPU部分,然後幫人裝一下系統。那麼LZ用JAVA語言怎麼寫出關係呢?

/***
 *
 *@Author ChenjunWang
 *@Description:操作系統接口
 *@Date: Created in 22:17 2018/3/24
 *@Modified By:
 *
 */
public interface OperationSystem {
    void operation();
}

/***
 *
 *@Author ChenjunWang
 *@Description:windows版本實現類
 *@Date: Created in 22:19 2018/3/24
 *@Modified By:
 *
 */
public class WindowsOs implements OperationSystem {
    @Override
    public void operation() {
        System.out.println("This is windows");
    }
}

/***
 *
 *@Author ChenjunWang
 *@Description:linux版本實現類
 *@Date: Created in 22:19 2018/3/24
 *@Modified By:
 *
 */
public class LinuxOS implements OperationSystem{
    @Override
    public void operation() {
        System.out.println("This is Linux");
    }
}


/***
 *
 *@Author ChenjunWang
 *@Description:i5 linux 電腦
 *@Date: Created in 22:24 2018/3/24
 *@Modified By:
 *
 */
public class I5CPULinuxComputer extends LinuxOS{
    public void detail() {
        System.out.println("This is i5 cpu");
    }
}


/***
 *
 *@Author ChenjunWang
 *@Description:i5 windows 電腦
 *@Date: Created in 22:24 2018/3/24
 *@Modified By:
 *
 */
public class I5CPUWindowsComputer extends WindowsOs{
    public void detail() {
        System.out.println("This is i5 cpu");
    }
}

/***
 *
 *@Author ChenjunWang
 *@Description:i7 linux 電腦
 *@Date: Created in 22:22 2018/3/24
 *@Modified By:
 *
 */
public class I7CPULinuxComputer extends LinuxOS{

    public void detail() {
        System.out.println("This is i7 cpu");
    }
}

/***
 *
 *@Author ChenjunWang
 *@Description:i7 windows 電腦
 *@Date: Created in 22:24 2018/3/24
 *@Modified By:
 *
 */
public class I7CPUWindowsComputer extends WindowsOs{
    public void detail() {
        System.out.println("This is i7 cpu");
    }
}

/***
 *
 *@Author ChenjunWang
 *@Description:客戶調用類
 *@Date: Created in 22:34 2018/3/24
 *@Modified By:
 *
 */
public class Client {
    public static void main(String[] args) {
        System.out.println("客戶買 linux i5版本!");
        I5CPULinuxComputer i5CPULinuxComputer = new I5CPULinuxComputer();
        i5CPULinuxComputer.operation();
        i5CPULinuxComputer.detail();


        System.out.println("客戶買 windows i5版本!");
        I5CPUWindowsComputer i5CPUWindowsComputer = new I5CPUWindowsComputer();
        i5CPUWindowsComputer.operation();
        i5CPUWindowsComputer.detail();
    }
}

運行結果如下
--------------------------

客戶買 linux i5版本!
This is Linux
This is i5 cpu
客戶買 windows i5版本!
This is windows
This is i5 cpu

從上面的例子可以看出,類直接的耦合度太高了,LZ假如要多賣一個操作系統的電腦,那麼就要加一個操作系統類,加2個電腦類(i5,i7),LZ在此基礎上在加一個i3的型號的電腦,LZ得在加3個類(對應3個操作系統版本)。是不是牽一髮動全身的感覺,類越多拓展越費勁。以後修改代碼的成本太高,這個時候LZ用橋接模式改造一下。

/***
 *
 *@Author ChenjunWang
 *@Description:操作系統接口
 *@Date: Created in 22:17 2018/3/24
 *@Modified By:
 *
 */
public interface OperationSystem {
    void operation();
}

/***
 *
 *@Author ChenjunWang
 *@Description:windows版本實現類
 *@Date: Created in 22:19 2018/3/24
 *@Modified By:
 *
 */
public class WindowsOs implements OperationSystem {
    @Override
    public void operation() {
        System.out.println("This is windows");
    }
}

/***
 *
 *@Author ChenjunWang
 *@Description:linux版本實現類
 *@Date: Created in 22:19 2018/3/24
 *@Modified By:
 *
 */
public class LinuxOS implements OperationSystem{
    @Override
    public void operation() {
        System.out.println("This is Linux");
    }
}
/***
 *
 *@Author ChenjunWang
 *@Description:電腦抽象類
 *@Date: Created in 22:44 2018/3/24
 *@Modified By:
 *
 */
abstract class Computer {
    private OperationSystem OS;
    public void setOS(OperationSystem OS){
        this.OS = OS;
    }
    abstract void detail();
    public void operation(){
        OS.operation();
    }
}

/***
 *
 *@Author ChenjunWang
 *@Description:i5實現類
 *@Date: Created in 22:57 2018/3/24
 *@Modified By:
 *
 */
public class I5CPUComputer extends Computer {
    public I5CPUComputer(OperationSystem OS) {
        setOS(OS);
    }

    @Override
    void detail() {
        System.out.println("This is i5 cpu");
    }
}

/***
 *
 *@Author ChenjunWang
 *@Description:i7 實現類
 *@Date: Created in 22:57 2018/3/24
 *@Modified By:
 *
 */
public class I7CPUComputer extends Computer {
    public I7CPUComputer(OperationSystem OS) {
        setOS(OS);
    }
    @Override
    void detail() {
        System.out.println("This is i7 cpu");
    }
}


/***
 *
 *@Author ChenjunWang
 *@Description:
 *@Date: Created in 22:34 2018/3/24
 *@Modified By:
 *
 */
public class Client {
    public static void main(String[] args) {
        System.out.println("客戶買 linux i5版本!");

        I5CPUComputer i5LinuxCPUComputer = new I5CPUComputer(new LinuxOS());
        i5LinuxCPUComputer.detail();
        i5LinuxCPUComputer.operation();

        System.out.println("客戶買 windows i5版本!");
        I5CPUComputer i5WindowsCPUComputer = new I5CPUComputer(new WindowsOs());
        i5WindowsCPUComputer.detail();
        i5WindowsCPUComputer.operation();

    }
}


運行結果如下
--------------------------

客戶買 linux i5版本!
This is i5 cpu
This is Linux
客戶買 windows i5版本!
This is i5 cpu
This is windows

現在從整體的代碼量上來看,差不懂,但是呢,現在對象之間的耦合度大大減少,當你填加新系統,或者cpu的時候,他們都是互不影響的。如果不解耦,現在的關係只有2層,假如有3層,那麼每加一個新的東西,那麼要添加的類實在太多了。你想想假如在加一個品牌層,A牌和B牌,不用橋接的模式的話,在加一個C牌,要加的類就是2層的類數乘以第三層的類數,LZ這裏就不展開講了。

總結

優點

(1)分離抽象接口及其實現部分。橋接模式使用“對象間的關聯關係”解耦了抽象和實現之間固有的綁定關係,使得抽象和實現可以沿着各自的維度來變化。所謂抽象和實現沿着各自維度的變化,也就是說抽象和實現不再在同一個繼承層次結構中,而是“子類化”它們,使它們各自都具有自己的子類,以便任何組合子類,從而獲得多維度組合對象。

(2)很多情況下橋接模式可以取代多層繼承方案,多層繼承方案違背了“單一職責原則”,複用性較差,且類的個數非常多,橋接模式是比多層繼承方案更好的解決方法,它極大減少了子類的個數。

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

(4)由於橋接模式把抽象部分和實現部分分離開了,所以在實現橋接的時候,就可以實現動態的選擇和使用具體的實現。也就是說一個實現不再是固定的綁定在一個抽象接口上了,可以實現運行期間動態地切換。(LZ的例子是可以自己換操作系統的,用setOS方法)

缺點

(1)橋接模式的使用會增加系統的理解與設計難度,由於關聯關係建立在抽象層,要求開發者一開始就針對抽象層進行設計與編程,對開發者對實際項目的理解程度息息相關。

Git地址

本篇實例Github地址:https://github.com/stackisok/Design-Pattern/tree/master/src/bridge

回到最上方


有什麼不懂或者不對的地方,歡迎留言。
喜歡LZ文章的小夥伴們,可以關注一波,也可以留言,LZ會回你們的。
覺得寫得不錯的小夥伴,歡迎轉載,但請附上原文地址,謝謝^_^!

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