描述
????橋接模式是將抽象部分與它的實現(xiàn)部分分離,使它們都可以獨立地變化。橋接模式是對象的結(jié)構(gòu)模式。又稱為柄體(Handle and Body)模式或接口(Interface)模式。
簡介

橋接模式結(jié)構(gòu)圖
????橋接的用意是“將抽象化(Abstraction)與實現(xiàn)化(Implementation)脫耦。這句話有三個關(guān)鍵詞,也就是抽象化、實現(xiàn)化和脫耦。
- 抽象化:從眾多的事物中抽取出共同的、本質(zhì)性的特征,而舍棄其非本質(zhì)的特征。例如佳能相機(jī),索尼相機(jī),尼康相機(jī),徠卡相機(jī)等,它們共同的特性就是相機(jī)。
- 實現(xiàn)化:針對抽象化給出的具體實現(xiàn)。它和抽象化是一個互逆的過程,實現(xiàn)化是對抽象化事物的進(jìn)一步具體化。
- 脫耦:脫耦就是將抽象化和實現(xiàn)化之間的耦合解脫開,或者說是將它們之間的強關(guān)聯(lián)改換成弱關(guān)聯(lián),將兩個角色之間的繼承關(guān)系改為關(guān)聯(lián)關(guān)系。
角色
- 抽象化(Abstraction)角色:抽象化給出的定義,并保存一個對實現(xiàn)化對象的引用。
- 修正抽象化(RefinedAbstraction)角色:擴(kuò)展抽象化角色,改變和修正父類對抽象化的定義。
- 實現(xiàn)化(Implementor)角色:這個角色給出實現(xiàn)化角色的接口,但不給出具體的實現(xiàn)。必須指出的是,這個接口不一定和抽象化角色的接口定義相同,實際上,這兩個接口可以非常不一樣。實現(xiàn)化角色應(yīng)當(dāng)只給出底層操作,而抽象化角色應(yīng)當(dāng)只給出基于底層操作的更高一層的操作。
- 具體實現(xiàn)化(ConcreteImplementor)角色:這個角色給出實現(xiàn)化角色接口的具體實現(xiàn)。
優(yōu)缺點
優(yōu)點
- 分離抽象接口及其實現(xiàn)部分。提高了比繼承更好的解決方案。
- 橋接模式提高了系統(tǒng)的可擴(kuò)充性,在兩個變化維度中任意擴(kuò)展一個維度,都不需要修改原有系統(tǒng)。
缺點
- 橋接模式的引入會增加系統(tǒng)的理解與設(shè)計難度,由于聚合關(guān)聯(lián)關(guān)系建立在抽象層,要求開發(fā)者針對抽象進(jìn)行設(shè)計與編程。
- 接模式要求正確識別出系統(tǒng)中兩個獨立變化的維度,因此其使用范圍具有一定的局限性。
使用場景
- 如果一個系統(tǒng)需要在構(gòu)件的抽象化角色和具體化角色之間增加更多的靈活性,避免在兩個層次之間建立靜態(tài)的繼承聯(lián)系,通過橋接模式可以使它們在抽象層建立一個關(guān)聯(lián)關(guān)系。
- 對于那些不希望使用繼承或因為多層次繼承導(dǎo)致系統(tǒng)類的個數(shù)急劇增加的系統(tǒng),橋接模式尤為適用。
- 一個類存在兩個獨立變化的維度,且這兩個維度都需要進(jìn)行擴(kuò)展。
示例
????假如有這樣一個業(yè)務(wù)場景:導(dǎo)出項目的需求。
????從業(yè)務(wù)上看,導(dǎo)出格式又分成word格式、execl格式、pdf格式等多種,不同的格式類型,業(yè)務(wù)功能處理是不一樣的;從導(dǎo)出的手段上看,又有直接下載、發(fā)送到郵件、導(dǎo)出到系統(tǒng)個人空間內(nèi)等。
/**
* 實現(xiàn)化(Implementor)角色
*/
public interface ExportWay {
void export(String requirement);
}
/**
* 具體實現(xiàn)化(ConcreteImplementor)角色
*/
public class EmailExport implements ExportWay {
@Override
public void export(String requirement) {
System.out.println("通過郵件導(dǎo)出需求:" + requirement);
}
}
/**
* 具體實現(xiàn)化(ConcreteImplementor)角色
*/
public class DownloadExport implements ExportWay {
@Override
public void export(String requirement) {
System.out.println("通過直接下載導(dǎo)出需求:" + requirement);
}
}
/**
* 具體實現(xiàn)化(ConcreteImplementor)角色
*/
public class EmailExport implements ExportWay {
@Override
public void export(String requirement) {
System.out.println("通過郵件導(dǎo)出需求:" + requirement);
}
}
/**
* 抽象化(Abstraction)角色
*/
public abstract class ExportRequirement {
/**
* 持有一個實現(xiàn)部分的對象
*/
private ExportWay exportWay;
public ExportRequirement(ExportWay exportWay) {
this.exportWay = exportWay;
}
public void exportFormat(String requirement) {
this.exportWay.export(requirement);
}
}
/**
* 修正抽象化(RefinedAbstraction)角色
*/
public class PdfFormat extends ExportRequirement {
public PdfFormat(ExportWay exportWay) {
super(exportWay);
}
@Override
public void exportFormat(String requirement) {
System.out.println("導(dǎo)出PDF格式的需求");
super.exportFormat(requirement);
}
}
/**
* 修正抽象化(RefinedAbstraction)角色
*/
public class WordFormat extends ExportRequirement{
public WordFormat(ExportWay exportWay) {
super(exportWay);
}
@Override
public void exportFormat(String requirement) {
System.out.println("導(dǎo)出word格式的需求");
super.exportFormat(requirement);
}
}
/**
* 修正抽象化(RefinedAbstraction)角色
*/
public class ExcelFormat extends ExportRequirement {
public ExcelFormat(ExportWay exportWay) {
super(exportWay);
}
@Override
public void exportFormat(String requirement) {
System.out.println("導(dǎo)出excel格式的需求");
super.exportFormat(requirement);
}
}