欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java設(shè)計(jì)模式之橋接模式

 更新時(shí)間:2022年10月11日 09:07:45   作者:tianClassmate  
這篇文章介紹了Java設(shè)計(jì)模式之橋接模式,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

本文通過(guò)老王和小王買(mǎi)車(chē),引出設(shè)計(jì)模式中的結(jié)構(gòu)型設(shè)計(jì)之橋接模式,接著說(shuō)明設(shè)計(jì)型模式的概念和代碼實(shí)現(xiàn),為了加深理解,會(huì)說(shuō)明適配器設(shè)計(jì)模式在JDBC中的應(yīng)用,最后談?wù)剺蚪幽J胶瓦m配器模式的總結(jié)。

讀者可以拉取完整代碼到本地進(jìn)行學(xué)習(xí),實(shí)現(xiàn)代碼均測(cè)試通過(guò)后上傳到碼云本地源碼下載。

一、引出問(wèn)題

老王和小王去奔馳4S店買(mǎi)車(chē),奔馳4S店的各種品牌型號(hào)琳瑯滿目,老王想試駕奔馳E、小王想試駕奔馳G,并且提出兩種奔馳型號(hào)的各種顏色都想體驗(yàn)一把,這讓店小二犯了難,兩兩組合就是很多種,4S店壓根放不下。

無(wú)奈店小二求救經(jīng)理,經(jīng)理出了一個(gè)注意:將奔馳E和G開(kāi)的品牌抽象出來(lái),將顏色也抽象出來(lái),通過(guò)品牌和顏色的組合代替繼承關(guān)系,減少了顏色和品牌的耦合,且減少了車(chē)的個(gè)數(shù),只需要兩臺(tái)就夠了。

果然經(jīng)理不愧是經(jīng)理。

經(jīng)理所說(shuō)的其實(shí)就是橋接模式。這種模式涉及到一個(gè)作為橋接的接口,使得實(shí)體類(lèi)的功能獨(dú)立于接口實(shí)現(xiàn)類(lèi)。這兩種類(lèi)型的類(lèi)可被結(jié)構(gòu)化改變而互不影響。

二、概念與使用

我們看一些概念:橋接(Bridge)是用于把抽象化與實(shí)現(xiàn)化解耦,使得二者可以獨(dú)立變化。這種類(lèi)型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式,它通過(guò)提供抽象化和實(shí)現(xiàn)化之間的橋接結(jié)構(gòu),來(lái)實(shí)現(xiàn)二者的解耦。

在該模式中應(yīng)該涉及到四個(gè)角色:

①實(shí)現(xiàn)類(lèi)接口(Implementor):定義實(shí)現(xiàn)角色的接口,供擴(kuò)展抽象化角色使用,例如抽象出奔馳品牌benz 可以擴(kuò)展出 benzE benzG

②具體實(shí)現(xiàn)角色(ConcreteImplementor):實(shí)現(xiàn)類(lèi)的具體實(shí)現(xiàn),例如各種奔馳品牌

③抽象化(Abstraction)角色:定義一個(gè)抽象類(lèi),其中引用了實(shí)現(xiàn)化角色(想要組合),例如汽車(chē)產(chǎn)品

④擴(kuò)展抽象化(RefinedAbstraction)角色:抽象化角色子類(lèi),實(shí)現(xiàn)父類(lèi)方法,且通過(guò)組合關(guān)系調(diào)用實(shí)現(xiàn)化角色中的業(yè)務(wù)方法,例如具體奔馳產(chǎn)品,紅色奔馳、白色奔馳

根據(jù)該模式的定義,我們將奔馳品牌抽象出來(lái),然后各品牌有各自的實(shí)現(xiàn),每個(gè)顏色的車(chē)把車(chē)品牌組合進(jìn)來(lái),在客戶端中每個(gè)相機(jī)類(lèi)型和相機(jī)品牌都能兩兩組合。

我們看具體的代碼實(shí)現(xiàn):

實(shí)現(xiàn)類(lèi)接口:

/**
 * 奔馳品牌類(lèi)
 * @author tcy
 * @Date 05-08-2022
 */
public interface BenzBrand {
    void showInfo();
}

具體實(shí)現(xiàn)角色1:

/**
 * @author tcy
 * @Date 05-08-2022
 */
public class BenzE implements BenzBrand{
    @Override
    public void showInfo() {
        System.out.print("【奔馳E】顏色是:");
    }
}

具體實(shí)現(xiàn)角色2:

/**
 * @author tcy
 * @Date 05-08-2022
 */
public class BenzG implements BenzBrand{
    @Override
    public void showInfo() {
        System.out.print("【奔馳G】顏色是:");

    }
}

抽象化角色:

/**
 * 抽象奔馳類(lèi)
 * @author tcy
 * @Date 05-08-2022
 */
public abstract class Benz {
    // 將品牌組合進(jìn)來(lái)
    protected BenzBrand benzBrand;

    public Benz(BenzBrand benzBrand) {
        this.benzBrand = benzBrand;
    }

    public void showInfo(){
        benzBrand.showInfo();
    }
}

擴(kuò)展抽象化1:

/**
 * @author tcy
 * @Date 05-08-2022
 */
public class BlackBenz extends Benz {
    public BlackBenz(BenzBrand benzBrand) {
        super(benzBrand);
    }

    @Override
    public void showInfo() {
        super.showInfo();

        System.out.println("黑色...");
    }
}

擴(kuò)展抽象化2:

/**
 * @author tcy
 * @Date 05-08-2022
 */
public class RedBenz extends Benz {
    public RedBenz(BenzBrand benzBrand) {
        super(benzBrand);
    }
    @Override
    public void showInfo() {
        super.showInfo();
        System.out.println("紅色...");
    }
}

客戶端調(diào)用:

/**
 * @author tcy
 * @Date 05-08-2022
 */
public class Client {

    public static void main(String[] args) {
        // 黑色奔馳E
        Benz benz1 = new BlackBenz(new BenzE());
        benz1.showInfo();
        // 黑色奔馳G
        Benz benz2 = new BlackBenz(new BenzG());
        benz2.showInfo();
        // 紅色奔馳E
        Benz benz3 = new RedBenz(new BenzE());
        benz3.showInfo();
        // 紅色奔馳G
        Benz benz4 = new RedBenz(new BenzG());
        benz4.showInfo();
    }
}

【奔馳E】顏色是:黑色...
【奔馳G】顏色是:黑色...
【奔馳E】顏色是:紅色...
【奔馳G】顏色是:紅色...

這樣即使老王提出來(lái)新的顏色、新的車(chē)型,只需要增加相應(yīng)的具體實(shí)現(xiàn)角色或者擴(kuò)展抽象化角色即可。

顧名思義,橋接模式就像是一個(gè)橋,可以用來(lái)連接兩個(gè)不同地方,這兩個(gè)地方自由發(fā)展,中間的貿(mào)易是通過(guò)一座橋來(lái)連接。

這種方法的缺點(diǎn)也很顯著,汽車(chē)能很快的確立型號(hào)和顏色兩個(gè)維度,在實(shí)際業(yè)務(wù)開(kāi)發(fā)中,識(shí)別出系統(tǒng)兩個(gè)獨(dú)立變化的維度就不簡(jiǎn)單了。

不難看出,列舉的例子有些過(guò)于強(qiáng)求,在現(xiàn)實(shí)世界中是永遠(yuǎn)不可能發(fā)生的,為了加深理解我找了大量在JDK亦或是Spirng等各種框架對(duì)橋接模式的應(yīng)用,只找到了橋接模式在Jdbc中的應(yīng)用。

三、應(yīng)用

我們都知道通過(guò)JDBC可以完成Java對(duì)關(guān)系型數(shù)據(jù)庫(kù)的SQL操作,我們?cè)谶B接數(shù)據(jù)數(shù)據(jù)庫(kù)時(shí),想必都接觸過(guò)Driver,在連接MySQL和Oracle的Driver都是不同的,這些都是實(shí)現(xiàn)接口類(lèi)。

我們看一下MySQL中實(shí)現(xiàn)的Driver類(lèi)。

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!");
        }
    }
}

在該類(lèi)中實(shí)際上有兩個(gè)作用,一是調(diào)用了DriverManager中的registerDriver方法來(lái)注冊(cè)驅(qū)動(dòng),二是當(dāng)驅(qū)動(dòng)注冊(cè)完成后,我們就會(huì)開(kāi)始調(diào)用DriverManager中的getConnection方法了。

我們看DriverManager的完整代碼:

    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");
}
}
}

在Java中通過(guò)Connection提供給各個(gè)數(shù)據(jù)庫(kù)一樣的操作接口,這里的Connection可以看作抽象類(lèi)。

可以說(shuō)我們用來(lái)操作不同數(shù)據(jù)庫(kù)的方法都是相同的,不過(guò)MySQL有自己的ConnectionImpl類(lèi),同樣Oracle也有對(duì)應(yīng)的實(shí)現(xiàn)類(lèi)。

這里Driver和Connection之間是通過(guò)DriverManager類(lèi)進(jìn)行橋接的,這種橋接模式和我們上面可以清晰的看出來(lái)各個(gè)角色是不同的。

四、總結(jié)

橋接模式是很好理解的,相信認(rèn)真看了實(shí)例的同學(xué)應(yīng)該都可以看懂,但那并不代表你已經(jīng)掌握了該設(shè)計(jì)模式。在我們使用JDBC的時(shí)候,想必有很多同學(xué)并不能看出來(lái)這是橋接模式。

紙上得來(lái)終覺(jué)淺,有一部分例子是為了說(shuō)明橋接模式而“構(gòu)想”出來(lái)的,各個(gè)角色都是清晰直觀??戳诉@樣的代碼,可以學(xué)會(huì)橋接模式,但是到了實(shí)際中很可能還是不會(huì)用。

最好的方法就是給出真實(shí)項(xiàng)目里的例子。但是這個(gè)難度確實(shí)很大,一到了真實(shí)項(xiàng)目里,就會(huì)遇到很多細(xì)節(jié)問(wèn)題,從而影響對(duì)模式的理解,而且真實(shí)項(xiàng)目都帶有一定的業(yè)務(wù)環(huán)境。

看懂并且學(xué)會(huì)了設(shè)計(jì)模式是一回事,在實(shí)際開(kāi)發(fā)中擇優(yōu)選擇設(shè)計(jì)模式那是另外一回事,這不僅需要對(duì)各個(gè)設(shè)計(jì)模式理解到位,更多的是對(duì)業(yè)務(wù)的理解和代碼理念的把控。

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接

相關(guān)文章

  • springboot+redis 實(shí)現(xiàn)分布式限流令牌桶的示例代碼

    springboot+redis 實(shí)現(xiàn)分布式限流令牌桶的示例代碼

    這篇文章主要介紹了springboot+redis 實(shí)現(xiàn)分布式限流令牌桶 ,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • Spring Boot項(xiàng)目如何同時(shí)支持HTTP和HTTPS協(xié)議的實(shí)現(xiàn)

    Spring Boot項(xiàng)目如何同時(shí)支持HTTP和HTTPS協(xié)議的實(shí)現(xiàn)

    這篇文章主要介紹了Spring Boot項(xiàng)目如何同時(shí)支持HTTP和HTTPS協(xié)議的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • 一篇文章帶你入門(mén)java運(yùn)算符

    一篇文章帶你入門(mén)java運(yùn)算符

    這篇文章主要介紹了Java基本數(shù)據(jù)類(lèi)型和運(yùn)算符,結(jié)合實(shí)例形式詳細(xì)分析了java基本數(shù)據(jù)類(lèi)型、數(shù)據(jù)類(lèi)型轉(zhuǎn)換、算術(shù)運(yùn)算符、邏輯運(yùn)算符等相關(guān)原理與操作技巧,需要的朋友可以參考下
    2021-08-08
  • Java使用quartz實(shí)現(xiàn)定時(shí)任務(wù)示例詳解

    Java使用quartz實(shí)現(xiàn)定時(shí)任務(wù)示例詳解

    這篇文章主要為大家介紹了Java使用quartz實(shí)現(xiàn)定時(shí)任務(wù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • OAuth2生成token代碼備忘實(shí)現(xiàn)過(guò)程示例

    OAuth2生成token代碼備忘實(shí)現(xiàn)過(guò)程示例

    這篇文章主要為大家介紹了OAuth2生成token代碼備忘實(shí)現(xiàn)過(guò)程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • java的JIT 工作原理簡(jiǎn)單介紹

    java的JIT 工作原理簡(jiǎn)單介紹

    這篇文章主要介紹了java的JIT 工作原理簡(jiǎn)單介紹的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • java Arrays工具類(lèi)實(shí)例詳解

    java Arrays工具類(lèi)實(shí)例詳解

    這篇文章主要介紹了java Arrays工具類(lèi)實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • SpringBoot AOP使用筆記

    SpringBoot AOP使用筆記

    今天小編就為大家分享一篇關(guān)于SpringBoot AOP使用筆記,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-01-01
  • Java通過(guò)工廠、Map容器創(chuàng)建對(duì)象的方法

    Java通過(guò)工廠、Map容器創(chuàng)建對(duì)象的方法

    這篇文章主要介紹了Java通過(guò)工廠、Map容器創(chuàng)建對(duì)象的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • 如何解決Gradle、Maven項(xiàng)目build后沒(méi)有mybatis的mapper.xml文件的問(wèn)題

    如何解決Gradle、Maven項(xiàng)目build后沒(méi)有mybatis的mapper.xml文件的問(wèn)題

    這篇文章主要介紹了如何解決Gradle、Maven項(xiàng)目build后沒(méi)有mybatis的mapper.xml文件的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01

最新評(píng)論