基本介紹
定義
將抽象部分與實(shí)現(xiàn)部分分離,使它們都可以獨(dú)立的變化。
介紹
- 橋接模式屬于結(jié)構(gòu)型模式。
- 舉個(gè)生活中的例子,一條數(shù)據(jù)線(xiàn),一頭USB接口的可以連接電腦、充電寶等等,另一頭可以連接不同品牌的手機(jī),通過(guò)這條數(shù)據(jù)線(xiàn),兩頭不同的東西就可以連接起來(lái),這就是橋接模式。
UML類(lèi)圖

角色說(shuō)明:
- Abstraction(抽象化角色):一般是抽象類(lèi),定義該角色的行為,同時(shí)保存一個(gè)對(duì)實(shí)現(xiàn)化角色的引用。
- Implementor(實(shí)現(xiàn)化角色):接口或者抽象類(lèi),定義角色必需的行為和屬性。
- ConcreteImplementorA、ConcreteImplementorB(具體實(shí)現(xiàn)化角色):實(shí)現(xiàn)角色的具體行為。
具體實(shí)現(xiàn)
這里以穿衣服為例,不同職業(yè)的人可能要穿的衣服不一樣。
1、創(chuàng)建實(shí)現(xiàn)化角色。定義一個(gè)衣服接口:
interface Clothes {
String getName();
}
2、創(chuàng)建具體實(shí)現(xiàn)化角色。創(chuàng)建兩種衣服類(lèi):校服和襯衫。
public class Uniform implements Clothes {
@Override
public String getName() {
return "校服";
}
}
public class Shirt implements Clothes {
@Override
public String getName() {
return "襯衫";
}
}
3、創(chuàng)建抽象化角色。定義一個(gè)人物類(lèi),有一個(gè)穿衣服的方法,并且持有衣服類(lèi)的引用。即抽象化角色持有實(shí)現(xiàn)化角色的引用,可以調(diào)用實(shí)現(xiàn)化角色的方法,達(dá)到橋接的作用。
public abstract class Person {
// 持有衣服類(lèi)的引用
Clothes mClothes;
public void setClothes(Clothes clothes) {
mClothes = clothes;
}
// 穿衣服
protected abstract void dress();
}
4、創(chuàng)建具體抽象化角色。這里有兩種角色穿衣服:學(xué)生和程序員。
public class Student extends Person {
@Override
protected void dress() {
System.out.println("學(xué)生穿上" + mClothes.getName());
}
}
public class Coder extends Person {
@Override
protected void dress() {
System.out.println("程序員穿上" + mClothes.getName());
}
}
5、客戶(hù)端測(cè)試:
public void test() {
// 創(chuàng)建各種衣服對(duì)象
Clothes uniform = new Uniform();
Clothes shirt = new Shirt();
// 不同職業(yè)的人穿衣服
Person coder = new Coder();
coder.setClothes(shirt);
coder.dress();
System.out.println("--------------------------------------");
Person student = new Student();
student.setClothes(uniform);
student.dress();
System.out.println("--------------------------------------");
student.setClothes(shirt);
student.dress();
}
輸出結(jié)果:
程序員穿上襯衫
--------------------------------------
學(xué)生穿上校服
--------------------------------------
學(xué)生穿上襯衫
6、其他說(shuō)明:
通過(guò)上面的例子可以看到,我們分離了兩端的變化。新增衣服和新增職業(yè)都變的非常簡(jiǎn)單。假如我們?cè)僭鲆粋€(gè)維度的變化,例如加個(gè)年齡來(lái)區(qū)分怎么辦?這時(shí)我們就可以把Person類(lèi)作為實(shí)現(xiàn)化角色,把不同年齡段作為抽象化角色,代碼就不寫(xiě)了,有興趣可以去實(shí)現(xiàn)一下。
模式總結(jié)
應(yīng)用場(chǎng)景
- 一個(gè)類(lèi)存在兩個(gè)或以上的獨(dú)立維度的變化,且這些維度都需要進(jìn)行拓展。
- 不希望使用繼承或因?yàn)槎鄬哟卫^承導(dǎo)致類(lèi)的個(gè)數(shù)急劇增加時(shí)。
- 如果一個(gè)系統(tǒng)需要在構(gòu)件的抽象化角色和具體化角色之間增加更多的靈活性,避免在兩個(gè)層次之間建立靜態(tài)的繼承關(guān)系,可以通過(guò)橋接模式使他們?cè)诔橄髮咏⒁粋€(gè)關(guān)聯(lián)關(guān)系。
優(yōu)點(diǎn)
- 分離了抽象與實(shí)現(xiàn)。讓抽象部分和實(shí)現(xiàn)部分獨(dú)立開(kāi)來(lái),分別定義接口,這有助于對(duì)系統(tǒng)進(jìn)行分層,從而產(chǎn)生更好的結(jié)構(gòu)化的系統(tǒng)。
- 良好的擴(kuò)展性。抽象部分和實(shí)現(xiàn)部分都可以分別獨(dú)立擴(kuò)展,不會(huì)相互影響。
缺點(diǎn)
- 增加了系統(tǒng)的復(fù)雜性。
- 不容易設(shè)計(jì),抽象與實(shí)現(xiàn)的分離要設(shè)計(jì)得好比較有難度。
Android中的源碼分析
橋接模式在Android中的源碼應(yīng)用還是非常廣泛的。比如AbsListView跟ListAdapter之間就是一個(gè)橋接模式。
1、AbsListView 與ListAdapter 之間的橋接模式
相關(guān)代碼就不貼了,看下它們的UML類(lèi)圖就明白了。

這里AbsListView是抽象化角色,ListAdapter則是實(shí)現(xiàn)化角色。
2、其他
另外,Window 與 WindowManager 之間也是橋接模式。有興趣的可以去看下源碼體會(huì)體會(huì)。