這里摘抄一份他處的概念绝页,你可以不必理會,先看下面得講解與實(shí)例寂恬,然后返回來理解概念续誉,不然抽象的概念會讓你崩潰...
橋接(Bridge)是用于把抽象化與實(shí)現(xiàn)化解耦,使得二者可以獨(dú)立變化掠剑。這種類型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式屈芜,它通過提供抽象化和實(shí)現(xiàn)化之間的橋接結(jié)構(gòu),來實(shí)現(xiàn)二者的解耦朴译。
這種模式涉及到一個(gè)作為橋接的接口井佑,使得實(shí)體類的功能獨(dú)立于接口實(shí)現(xiàn)類。這兩種類型的類可被結(jié)構(gòu)化改變而互不影響眠寿。
個(gè)人理解:橋接是一個(gè)接口躬翁,它與一方應(yīng)該是綁定的,也就是解耦的雙方中的一方必然是繼承這個(gè)接口的盯拱,這一方就是實(shí)現(xiàn)方盒发,而另一方正是要與這一方解耦的抽象方,如果不采用橋接模式狡逢,一般我們的處理方式是直接使用繼承來實(shí)現(xiàn)宁舰,這樣雙方之間處于強(qiáng)鏈接,類之間關(guān)聯(lián)性極強(qiáng)奢浑,如要進(jìn)行擴(kuò)展蛮艰,必然導(dǎo)致類結(jié)構(gòu)急劇膨脹。采用橋接模式雀彼,正是為了避免這一情況的發(fā)生壤蚜,將一方與橋綁定即寡,即實(shí)現(xiàn)橋接口,另一方在抽象類中調(diào)用橋接口(指向的實(shí)現(xiàn)類)袜刷,這樣橋方可以通過實(shí)現(xiàn)橋接口進(jìn)行單方面擴(kuò)展聪富,而另一方可以繼承抽象類而單方面擴(kuò)展,而之間的調(diào)用就從橋接口來作為突破口著蟹,不會受到雙方擴(kuò)展的任何影響墩蔓。
下面的實(shí)例能真正體現(xiàn)著一點(diǎn):
實(shí)例準(zhǔn)備:我們假設(shè)有一座橋,橋左邊為A草则,橋右邊為B钢拧,A有A1蟹漓,A2炕横,A3等,表示橋左邊的三個(gè)不同地方葡粒,B有B1份殿,B2,B3等嗽交,表示橋右邊的三個(gè)不同地方卿嘲,假設(shè)我們要從橋左側(cè)A出發(fā)到橋的右側(cè)B,我們可以有多重方案夫壁,A1到B1拾枣,A1到B2,A1到B3盒让,A2到B1...等等梅肤,以此為例,代碼如下:
橋接口:Qiao
public interface Qiao {
//目的地B
? ? void targetAreaB();
}
目的地B1,B2,B3:
/**
* 目的地B1
*/
public class TargetAreaB1implements Qiao {
@Override
? ? public void targetAreaB() {
System.out.println("我要去B1");
? ? }
}
/**
* 目的地B2
*/
public class TargetAreaB2implements Qiao {
@Override
? ? public void targetAreaB() {
System.out.println("我要去B2");
? ? }
}
/**
* 目的地B3
*/
public class TargetAreaB3implements Qiao {
@Override
? ? public void targetAreaB() {
System.out.println("我要去B3");
? ? }
}
抽象來源地:SourceAreaA
public abstract class SourceAreaA {
//引用橋接口
? ? Qiaoqiao;
? ? //來源地
? ? abstract void fromAreaA();
}
來源地A1邑茄,A2姨蝴,A3:
/**
* 來源地A1
*/
public class SourceAreaA1extends SourceAreaA {
@Override
? ? void fromAreaA() {
System.out.println("我來自A1");
? ? }
}
/**
* 來源地A2
*/
public class SourceAreaA2extends SourceAreaA {
@Override
? ? void fromAreaA() {
System.out.println("我來自A2");
? ? }
}
/**
* 來源地A3
*/
public class SourceAreaA3extends SourceAreaA {
@Override
? ? void fromAreaA() {
System.out.println("我來自A3");
? ? }
}
客戶端:Clienter
public class Clienter {
public static void main(String[] args) {
SourceAreaA a =new SourceAreaA2();
? ? ? ? a.qiao =new TargetAreaB3();
? ? ? ? a.fromAreaA();
? ? ? ? a.qiao.targetAreaB();
? ? }
}
運(yùn)行結(jié)果:
如何,只要你認(rèn)真看完了實(shí)例肺缕,你就明白了這種模式的好處左医,現(xiàn)在我們要添加來源地和目的地,只要繼續(xù)繼承AreaA和實(shí)現(xiàn)Qiao即可同木,之前我所說的綁定浮梢,正式此處將橋與目的地綁定在一起,使用一個(gè)接口完成彤路。
其實(shí)要完成橋接模式秕硝,注意點(diǎn)并不多,重在理解模式的使用場景斩萌。
注意點(diǎn):
1缝裤、定義一個(gè)橋接口屏轰,使其與一方綁定,這一方的擴(kuò)展全部使用實(shí)現(xiàn)橋接口的方式憋飞。
2霎苗、定義一個(gè)抽象類,來表示另一方榛做,在這個(gè)抽象類內(nèi)部要引入橋接口唁盏,而這一方的擴(kuò)展全部使用繼承該抽象類的方式。
其實(shí)我們可以發(fā)現(xiàn)橋接模式應(yīng)對的場景有方向性的检眯,橋綁定的一方都是被調(diào)用者厘擂,屬于被動(dòng)方,抽象方屬于主動(dòng)方锰瘸。
其實(shí)我的JDK提供的JDBC數(shù)據(jù)庫訪問接口API正是經(jīng)典的橋接模式的實(shí)現(xiàn)者刽严,接口內(nèi)部可以通過實(shí)現(xiàn)接口來擴(kuò)展針對不同數(shù)據(jù)庫的具體實(shí)現(xiàn)來進(jìn)行擴(kuò)展,而對外的僅僅只是一個(gè)統(tǒng)一的接口調(diào)用避凝,調(diào)用方過于抽象舞萄,可以將其看做每一個(gè)JDBC調(diào)用程序(這是真實(shí)實(shí)物,當(dāng)然不存在抽象)
下面來理解一下開頭的概念:
橋接(Bridge)是用于把抽象化與實(shí)現(xiàn)化解耦管削,使得二者可以獨(dú)立變化倒脓。這種類型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式,它通過提供抽象化和實(shí)現(xiàn)化之間的橋接結(jié)構(gòu)含思,來實(shí)現(xiàn)二者的解耦崎弃。
這種模式涉及到一個(gè)作為橋接的接口,使得實(shí)體類的功能獨(dú)立于接口實(shí)現(xiàn)類含潘。這兩種類型的類可被結(jié)構(gòu)化改變而互不影響饲做。
理解:此處抽象化與實(shí)現(xiàn)化分別指代實(shí)例中的雙方,而且實(shí)現(xiàn)化對應(yīng)目的地方(通過實(shí)現(xiàn)橋接口進(jìn)行擴(kuò)展)调鬓,抽象方對應(yīng)來源地方(通過繼承抽象類來進(jìn)行擴(kuò)展)艇炎,如果我們不使用橋接模式,我們會怎么想實(shí)現(xiàn)這個(gè)實(shí)例呢腾窝?很簡單缀踪,我們分別定義來源地A1、A2虹脯、A3類和目的地B1驴娃、B2、B3循集,然后具體的實(shí)現(xiàn)就是唇敞,A1到B1一個(gè)類,A1到B2一個(gè)類,等疆柔,如果我們要擴(kuò)展了A和B ,要直接增加An類和Bn類咒精,如此編寫不說類內(nèi)部重復(fù)性代碼多,而且還會導(dǎo)致類結(jié)構(gòu)的急劇膨脹旷档,最重要的是模叙,在通過繼承實(shí)現(xiàn)路徑的時(shí)候,會造成雙方耦合性增大鞋屈,而這又進(jìn)一步加劇了擴(kuò)展的復(fù)雜性范咨。使用橋結(jié)構(gòu)模式可以很好地規(guī)避這些問題:重在解耦。