1.前言
通過前面的學習晤碘,可以發(fā)現(xiàn):當一個對象持有另一個對象時,其實可以理解為兩個對象進行了關(guān)聯(lián)友题。這種關(guān)系不像類的繼承是靜態(tài)的嗤堰、不可變得,相反具有很高的靈活性度宦,是常見的解耦方式踢匣。當耦合度低時,持有者和被持有者可以獨立變化戈抄,甚至進行擴展离唬,而不會相互影響。
2.概念
橋接模式將抽象部分與實現(xiàn)部分分離划鸽,使它們都可以獨立地進行變化输莺。其中,“橋接”就是指以橋梁的方式進行連接裸诽,而連接的對象是分離后的抽象部分與實現(xiàn)部分嫂用。
一個類的屬性各自發(fā)生著變化,并對類產(chǎn)生著影響丈冬,說明它有不同維度的改變嘱函,而“抽象”、“實現(xiàn)”就是這樣的兩個維度埂蕊。以杯裝咖啡舉個例子往弓,若將它抽象為類,則有屬性杯子和咖啡蓄氧。有點不同的是函似,在橋接模式中,“杯裝咖啡”對象實際只有杯子的功能匀们,通過持有“咖啡”對象具有了完整的功能缴淋。下面的場景中,注意與裝飾模式進行比較泄朴。
3.場景
有一天去咖啡店重抖,你點了杯咖啡。店員肯定會問你祖灰,想要什么咖啡钟沛,你可以選擇藍山的、拿鐵的局扶、不加糖的等恨统;選完后叁扫,有的店員還會問,你喜歡什么樣的杯子畜埋,可以是玻璃的莫绣、陶瓷的、印花的等悠鞍。
4.寫法
// 1.定義實現(xiàn)部分对室,通常為接口或抽象類
public interface Coffee {
// 2.定義此維度的行為
void make();
}
// 1.定義抽象部分,通常抽象類
public abstract class CupCoffee {
// 2.持有實現(xiàn)部分咖祭,及相關(guān)操作
private Coffee mCoffee;
public CupCoffee(Coffee coffee) {
mCoffee = coffee;
}
protected void make() {
mCoffee.make();
}
// 3.定義此維度的行為掩宜,可完善和擴展
public abstract void holder();
}
實現(xiàn)抽象部分和實現(xiàn)部分這兩個維度的具體邏輯,若有必要么翰,可進行完善和擴展牺汤。這里特別像裝飾模式,但請注意浩嫌,裝飾模式中檐迟,代理者和被代理者得實現(xiàn)相同的接口,而橋接模式的兩個部分是各自實現(xiàn)不同的抽象固该。
public class BlueMountain implements Coffee {
@Override
public void make() {
System.out.println("做了份藍山咖啡");
}
}
public class Latte implements Coffee {
@Override
public void make() {
System.out.println("做了份拿鐵咖啡");
}
}
public class Glass extends CupCoffee {
public Glass(Coffee coffee) {
super(coffee);
}
@Override
public void holder() {
make();
System.out.println("用玻璃杯來裝");
}
}
public class Ceramic extends CupCoffee {
public Ceramic(Coffee coffee) {
super(coffee);
}
@Override
public void holder() {
make();
System.out.println("用陶瓷杯來裝");
}
}
在使用時盡量使用接口或抽象類锅减,以降低耦合度,方便后期維護伐坏。
public class Client {
public static void main(String[] args) {
// 客戶可能選擇的邏輯
Coffee blueMountain = new BlueMountain();
new Glass(blueMountain).holder();
Coffee latte = new Latte();
new Ceramic(latte).holder();
}
}
5.總結(jié)
橋接模式其實沒什么明顯的缺點怔匣,若真要算,也許在什么情況下使用不好把控桦沉。因為任何多維度變化類或者說多個樹狀類之間的耦合都可以使用橋接模式來解耦每瞒,那么是否需要分離、如何分離纯露,這種恰到好處的尺度把握很考驗經(jīng)驗剿骨。畢竟過度分離,會導致抽象類和接口爆炸性的增加埠褪,反而導致代碼的可閱讀性降低浓利,甚至影響用戶的使用。