前言
橋接模式又稱橋梁模式厉熟,屬于結(jié)構(gòu)型模式抹估,是指將抽象化 與 實(shí)現(xiàn)化 脫耦廉丽,使得二者可以獨(dú)立的變化倦微。它是用組合關(guān)系代替繼承關(guān)系來實(shí)現(xiàn),從而降低了抽象和實(shí)現(xiàn)這兩個(gè)可變維度的耦合度正压。
定義
將抽象和行為劃分開來欣福,各自獨(dú)立,但能動(dòng)態(tài)的結(jié)合
結(jié)構(gòu)
橋接(Bridge)模式包含以下主要角色:
- 抽象化(Abstraction)角色 :定義抽象類焦履,并包含一個(gè)對(duì)實(shí)現(xiàn)化對(duì)象的引用拓劝。
- 擴(kuò)展抽象化(Refined Abstraction)角色 :是抽象化角色的子類,實(shí)現(xiàn)父類中的業(yè)務(wù)方法嘉裤,并通過組合關(guān)系調(diào)用實(shí)現(xiàn)化角色中的業(yè)務(wù)方法郑临。
- 實(shí)現(xiàn)化(Implementor)角色 :定義實(shí)現(xiàn)化角色的接口,供擴(kuò)展抽象化角色調(diào)用屑宠。
- 具體實(shí)現(xiàn)化(Concrete Implementor)角色 :給出實(shí)現(xiàn)化角色接口的具體實(shí)現(xiàn)厢洞。
為什么使用
通常,當(dāng)一個(gè)抽象類或接口有多個(gè)具體實(shí)現(xiàn)(concrete subclass),這些concrete之間關(guān)系可能有以下兩種:
- 這多個(gè)具體實(shí)現(xiàn)之間恰好是并列的,沒有概念上的重復(fù)躺翻,那么我們只要使用繼承就可以了
- 實(shí)際應(yīng)用上丧叽,常常有可能在這多個(gè)concrete class之間有概念上重疊,那么需要我們把抽象共同部分和行為共同部門各自獨(dú)立開來公你,原來是準(zhǔn)備放在一個(gè)接口里踊淳,現(xiàn)在需要設(shè)計(jì)兩個(gè)接口,分別放置抽象和行為省店。
如何實(shí)現(xiàn)
【例】視頻播放器
需要開發(fā)一個(gè)跨平臺(tái)視頻播放器嚣崭,可以在不同操作系統(tǒng)平臺(tái)(如Windows、Mac懦傍、Linux等)上播放多種格式的視頻文件雹舀,常見的視頻格式包括RMVB、AVI粗俱、WMV等说榆。該播放器包含了兩個(gè)維度,適合使用橋接模式寸认。
類圖如下:
橋接模式.png
代碼如下:
//視頻文件
public interface VideoFile {
void decode(String fileName);
}
//avi文件
public class AVIFile implements VideoFile {
public void decode(String fileName) {
System.out.println("avi視頻文件:"+ fileName);
}
}
//rmvb文件
public class REVBBFile implements VideoFile {
public void decode(String fileName) {
System.out.println("rmvb文件:" + fileName);
}
}
//操作系統(tǒng)版本
public abstract class OperatingSystemVersion {
protected VideoFile videoFile;
public OperatingSystemVersion(VideoFile videoFile) {
this.videoFile = videoFile;
}
public abstract void play(String fileName);
}
//Windows版本
public class Windows extends OperatingSystem {
public Windows(VideoFile videoFile) {
super(videoFile);
}
public void play(String fileName) {
videoFile.decode(fileName);
}
}
//mac版本
public class Mac extends OperatingSystemVersion {
public Mac(VideoFile videoFile) {
super(videoFile);
}
public void play(String fileName) {
videoFile.decode(fileName);
}
}
//測(cè)試類
public class Client {
public static void main(String[] args) {
OperatingSystem os = new Windows(new AVIFile());
os.play("戰(zhàn)狼3");
}
}
好處:
- 橋接模式提高了系統(tǒng)的可擴(kuò)充性签财,在兩個(gè)變化維度中任意擴(kuò)展一個(gè)維度,都不需要修改原有系統(tǒng)偏塞。
如:如果現(xiàn)在還有一種視頻文件類型wmv唱蒸,我們只需要再定義一個(gè)類實(shí)現(xiàn)VideoFile接口即可,其他類不需要發(fā)生變化灸叼。 - 實(shí)現(xiàn)細(xì)節(jié)對(duì)客戶透明
使用場(chǎng)景
- 當(dāng)一個(gè)類存在兩個(gè)獨(dú)立變化的維度神汹,且這兩個(gè)維度都需要進(jìn)行擴(kuò)展時(shí)。
- 當(dāng)一個(gè)系統(tǒng)不希望使用繼承或因?yàn)槎鄬哟卫^承導(dǎo)致系統(tǒng)類的個(gè)數(shù)急劇增加時(shí)古今。
- 當(dāng)一個(gè)系統(tǒng)需要在構(gòu)件的抽象化角色和具體化角色之間增加更多的靈活性時(shí)屁魏。避免在兩個(gè)層次之間建立靜態(tài)的繼承聯(lián)系,通過橋接模式可以使它們?cè)诔橄髮咏⒁粋€(gè)關(guān)聯(lián)關(guān)系捉腥。