簡介
橋接模式,也稱爲橋樑模式,英文是 Bridge Pattern。有兩種解釋:第一種,是經典的GOF《設計模式》中描述到,“將抽象和實現解耦,讓它們可以獨立變化”。第二種,是其他相關書籍中描述的,”一個類存在兩個(或多個)獨立變化的維度,我們通過組合的方式,讓這兩個(或多個)維度可以獨立進行擴展“。
注意:
對於第一種 GOF 的理解方式,弄懂定義中“抽象”和“實現”兩個概念,是理解它的關鍵。定義中的“抽象”,指的並非“抽象類”或“接口”,而是被抽象出來的一套“類庫”,它只包含骨架代碼,真正的業務邏輯需要委派給定義中的“實現”來完成。而定義中的“實現”,也並非“接口的實現類”,而是一套獨立的“類庫”。“抽象”和“實現”獨立開發,通過對象之間的組合關係,組裝在一起。”抽象“和”實現”實質上對應的是兩個獨立變化的維度。
適用範圍
1,一個類存在兩個或者多個獨立變化的維度,且者兩個或多個維度都需要進行擴展,就可以使用橋接模式;
2,任何多維度變化類或者說多個樹狀類之間的耦合都可以使用橋接模式來解耦;
實現
相信大家喝過奶茶,可以簡單把奶茶分爲大杯少糖,小杯少糖,大杯多糖,小杯多糖;可以發現一杯奶茶有兩個維度,一是:大杯,小杯;二是:少糖,多糖;下面我們用代碼實現;
定義奶茶類(“抽象”)
public abstract class MilkyTea {
protected MilkyTeaAdditives additives;
public MilkyTea(MilkyTeaAdditives additives) {
this.additives = additives;
}
//奶茶具體是什麼樣的,由子類實現
public abstract void makeMilkyTea();
}
MilkyTea通過組合引用了MilkyTeaAdditives;下面實現第一個維度:大杯小杯維度;
public class LargeMikyTea extends MilkyTea {
public LargeMikyTea(MilkyTeaAdditives additives) {
super(additives);
}
@Override
public void makeMilkyTea() {
System.out.println("大杯"+ additives.addSomething() + "奶茶" );
}
}
public class SmallMilkyTea extends MilkyTea {
public SmallMilkyTea(MilkyTeaAdditives additives) {
super(additives);
}
@Override
public void makeMilkyTea() {
System.out.println("小杯"+ additives.addSomething() + "奶茶");
}
}
對於加料糖,我們定義一個接口(“實現”)
public interface MilkyTeaAdditives {
String addSomething();
}
另一個維度:少糖和多糖,代碼實現如下:
public class LargeSugar implements MilkyTeaAdditives {
@Override
public String addSomething() {
return "多糖";
}
}
public class SmallSugar implements MilkyTeaAdditives {
@Override
public String addSomething() {
return "少糖";
}
}
成品
public class Client {
public static void main(String[] args) {
LargeSugar largeSugar = new LargeSugar();
SmallSugar smallSugar = new SmallSugar();
//大杯多糖
LargeMikyTea largeMikyTea = new LargeMikyTea(largeSugar);
largeMikyTea.makeMilkyTea();
//大杯少糖
LargeMikyTea largeMikyTea1 = new LargeMikyTea(smallSugar);
largeMikyTea1.makeMilkyTea();
//小杯多糖
SmallMilkyTea smallMilkyTea = new SmallMilkyTea(largeSugar);
smallMilkyTea.makeMilkyTea();
//小杯少糖
SmallMilkyTea smallMilkyTea1 = new SmallMilkyTea(smallSugar);
smallMilkyTea1.makeMilkyTea();
}
}
隨着市場變化,爲了滿足更多的客戶,現在推出中杯;
public class MiddleMilkyTea extends MilkyTea {
public MiddleMilkyTea(MilkyTeaAdditives additives) {
super(additives);
}
@Override
public void makeMilkyTea() {
System.out.println("中杯"+additives.addSomething() + "奶茶!");
}
}
對應的成品增加
public class Client {
public static void main(String[] args) {
LargeSugar largeSugar = new LargeSugar();
SmallSugar smallSugar = new SmallSugar();
//..................................
//中杯多糖
MiddleMilkyTea middleMilkyTea = new MiddleMilkyTea(largeSugar);
middleMilkyTea.makeMilkyTea();
//中杯少糖
MiddleMilkyTea middleMilkyTea1 = new MiddleMilkyTea(smallSugar);
middleMilkyTea1.makeMilkyTea();
}
}
但是僅僅增加中杯是不夠的,很多客戶需要添加其他的配料,比如珍珠,西米,紅豆等等,具體只需要實現MilkyTeaAdditives接口,增加其他配料就好,具體就不用代碼實現了;相信大家都能實現;
總結:兩個維度沒什麼交集,唯一的聯繫就是MilkTea中通過組合保持了對MilkTeaAdditives的引用,通過組合形成了兩者之間的紐帶,這就是橋接模式;