本文介紹了結構型設計模式中的橋接模式,講解了它的特點和相關構成,並通過相應的案例,使用Java代碼進行演示。 ...
設計模式—結構型模式之橋接模式
將抽象與實現解耦,使兩者都可以獨立變化。
在現實生活中,某些類具有兩個或多個維度的變化,如圖形既可按形狀分,又可按顏色分。如何設計類似於 Photoshop 這樣的軟體,能畫不同形狀和不同顏色的圖形呢?如果用繼承方式,m 種形狀和 n 種顏色的圖形就有 m×n 種,不但對應的子類很多,而且擴展困難。不同顏色和字體的文字、不同品牌和功率的汽車。
橋接將繼承轉為關聯,降低類之間的耦合度,減少代碼量。
橋接(Bridge)模式包含以下主要角色:
- 系統設計期間,如果這個類裡面的一些東西,會擴展很多,這個東西就應該分離出來
- 抽象化(Abstraction)角色:定義抽象類,並包含一個對實現化對象的引用。
- 擴展抽象化(Refined Abstraction)角色:是抽象化角色的子類,實現父類中的業務方法,並通過組合關係調用實現化角色中的業務方法。
- 實現化(Implementor)角色:定義實現化角色的介面,供擴展抽象化角色調用。
- 具體實現化(Concrete Implementor)角色:給出實現化角色介面的具體實現。
舉例
如果我們有不同型號的手機,每種型號的手機都有線下和線上兩種銷售渠道,兩種渠道的價格還不同。如果我們不使用設計模式,我們就需要定義線上渠道的不同型號手機類、線下渠道的不同型號手機類;如果我們再增加一個渠道,又需要增加新的不同型號渠道手機類。我們能否把渠道分離出來呢?這便引出了橋接模式。
渠道抽象類:
/**
* 抽象渠道類
*/
public abstract class AbstarctChnnel {
private String channel;
private Integer price;
public AbstarctChnnel(String channel, Integer price) {
this.channel = channel;
this.price = price;
}
String getChannelInfo(){
return "渠道:"+this.channel + "\t價格:"+this.price;
}
}
線上渠道和線下渠道分別為:
/**
* 線上渠道
*/
public class OnlineChannel extends AbstarctChnnel{
public OnlineChannel(String channel, Integer price) {
super(channel, price);
}
}
/**
* 線下渠道
*/
public class OfflineChannel extends AbstarctChnnel{
public OfflineChannel(String channel, Integer price) {
super(channel, price);
}
}
我們的抽象手機類如下:
public abstract class AbstarctPhone {
//橋接在此.....設計期間就得想好
//【真正會引起此類變化的一個維度直接抽取出來,通過組合的方式接起來】
//橋接+適配器 ...
AbstarctChnnel chnnel;
abstract String getPhone();
public void setChnnel(AbstarctChnnel chnnel) {
this.chnnel = chnnel;
}
}
手機類如下:
public class BananaPhone extends AbstarctPhone{
@Override
String getPhone() {
return "香蕉手機:"+this.chnnel.getChannelInfo();
}
}
測試類如下:
public class BridgeTest {
public static void main(String[] args) {
BananaPhone phone = new BananaPhone();
phone.setChnnel(new OfflineChannel("線下渠道",10000));
System.out.println("phone.getPhone() = " + phone.getPhone());
}
}
運行結果如下:
如果我們再新增一個渠道,只要再擴展出一個渠道類即可,不需要新增手機類。
總結
我們需要把真正會引起此類變化的維度,直接抽取出來,通過組合的方式拼接起來。