詳解Java設(shè)計(jì)模式之橋接模式
1 橋接模式的定義
橋接模式(Bridge Pattem):將抽象部分和實(shí)現(xiàn)部分分離,使它們都可以獨(dú)立地變化。它是一種對(duì)象結(jié)構(gòu)型模式,又稱柄體模式或者接口模式。
2 為什么引入橋接模式
當(dāng)用戶采用多繼承的方式實(shí)現(xiàn)代碼時(shí),增加一個(gè)新的種類非常不方便(可拓展性差)。如上圖,我想增加一個(gè)奧迪類,則需要在跑車中增加奧迪跑車類,在SUV中增加奧迪SUV類,這僅僅是兩個(gè),如果是多的話會(huì)更加的麻煩。
同時(shí)也違反了 單一職責(zé)原則。
橋接模式可以很好的優(yōu)化這一問(wèn)題。
3 橋接實(shí)戰(zhàn)
把上面的例子總結(jié)一下,可以得到如下的圖。
橋接模式的作用就如同中間的點(diǎn),將類型和品牌聯(lián)系起來(lái)。
3.1 代碼
Brand.interface
//品牌接口 public interface Brand { public void info(); }
BMW
public class BMW implements Brand{ @Override public void info() { System.out.print("寶馬"); } }
Benz
public class Benz implements Brand{ @Override public void info() { System.out.print("奔馳"); } }
Car
public abstract class Car { protected Brand brand; public Car(Brand brand) { this.brand = brand; } public void info() { brand.info(); } }
SportsCar
public class SportsCar extends Car{ public SportsCar(Brand brand) { super(brand); } @Override public void info() { super.info(); System.out.println("跑車"); } }
SUV
public class SUV extends Car{ public SUV(Brand brand) { super(brand); } @Override public void info() { super.info(); System.out.println("越野車"); } }
Client
public class Client { public static void main(String[] args) { //寶馬跑車 Car car = new SportsCar(new BMW()); car.info(); } }
3.2 類圖
將多繼承轉(zhuǎn)化為橋接模式之后,如果在想增加一個(gè)凱利拉克,就只需要在Car里面增加一個(gè)凱利拉克,而不需要對(duì)其他類進(jìn)行改動(dòng)。
4 橋接模式的優(yōu)缺點(diǎn)
4.1 優(yōu)點(diǎn)
- 橋接模式偶爾類似于多繼承方案,但是多繼承方案違背了類的單一職責(zé)原則,復(fù)用性比較差,類的個(gè)數(shù)也非常多,橋接模式是比多繼承方案更好的解決方法。極大的減少了子類的個(gè)數(shù),從而降低管理和維護(hù)的成本。
- 橋接模式提高了系統(tǒng)的可擴(kuò)充性,在兩個(gè)變化維度中任意拓展一個(gè)維度,都不需要修改原有的系統(tǒng)。符合開(kāi)閉原則,就像一座橋,可以把兩個(gè)變化的維度連接起來(lái)。
4.2 缺點(diǎn)
- 橋接模式的引入會(huì)增加系統(tǒng)的理解與設(shè)計(jì)難度,由于聚合關(guān)聯(lián)關(guān)系建立在抽象層,要求開(kāi)發(fā)者針對(duì)抽象進(jìn)行設(shè)計(jì)與編程。
- 橋接模式要求正確識(shí)別出系統(tǒng)中兩個(gè)獨(dú)立變化的維度,因此其使用范圍具有一定的局限性。
4.3 適用環(huán)境
如果一個(gè)系統(tǒng)需要在構(gòu)件的抽象化角色和具體化角色之間增加更多的靈活性,避免在兩個(gè)層次之間建立靜態(tài)的繼承聯(lián)系,通過(guò)橋接模式可以使它們?cè)诔橄髮咏⒁粋€(gè)關(guān)聯(lián)關(guān)系。
抽象化角色和實(shí)現(xiàn)化角色可以繼承的方式獨(dú)立擴(kuò)展而不相互影響,在程序運(yùn)行時(shí)可以動(dòng)態(tài)講一個(gè)抽象化子類的對(duì)象和一個(gè)實(shí)現(xiàn)化子類的對(duì)象進(jìn)行組合,即系統(tǒng)需要對(duì)抽象化角色和實(shí)現(xiàn)化角色進(jìn)行動(dòng)態(tài)耦合。
一個(gè)類存在兩個(gè)獨(dú)立變化的維度,且這兩個(gè)維度都需要進(jìn)行擴(kuò)展。雖然在系統(tǒng)中使用繼承是沒(méi)有問(wèn)題的,但是由于抽象化角色和具體化角色需要獨(dú)立變化,設(shè)計(jì)需求需要獨(dú)立管理這兩者。
對(duì)于那些不希望使用繼承或因?yàn)槎鄬哟卫^承導(dǎo)致系統(tǒng)類的個(gè)數(shù)急劇增加的系統(tǒng),橋接模式尤為適用。
4.4 場(chǎng)景
- Java語(yǔ)言通過(guò)Java虛擬機(jī)實(shí)現(xiàn)跨平臺(tái)性
- AWT中的Peer架構(gòu)
然在系統(tǒng)中使用繼承是沒(méi)有問(wèn)題的,但是由于抽象化角色和具體化角色需要獨(dú)立變化,設(shè)計(jì)需求需要獨(dú)立管理這兩者。
對(duì)于那些不希望使用繼承或因?yàn)槎鄬哟卫^承導(dǎo)致系統(tǒng)類的個(gè)數(shù)急劇增加的系統(tǒng),橋接模式尤為適用。
- Java語(yǔ)言通過(guò)Java虛擬機(jī)實(shí)現(xiàn)跨平臺(tái)性
- AWT中的Peer架構(gòu)
- JDBC驅(qū)動(dòng)程序也是橋接模式的應(yīng)用之一
到此這篇關(guān)于詳解Java設(shè)計(jì)模式之橋接模式的文章就介紹到這了,更多相關(guān)Java橋接模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot實(shí)現(xiàn)mock平臺(tái)的示例代碼
本文主要介紹了springboot實(shí)現(xiàn)mock平臺(tái)的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06Java實(shí)現(xiàn)圖書(shū)館借閱系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)圖書(shū)館借閱系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03SpringValidation自定義注解及分組校驗(yàn)功能詳解
這篇文章主要介紹了SpringValidation自定義注解及分組校驗(yàn)功能,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-01-01使用Spring底層組件實(shí)現(xiàn)Aware接口
這篇文章主要介紹了使用Spring底層組件實(shí)現(xiàn)Aware接口,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07Java面向?qū)ο蠡A(chǔ)知識(shí)之封裝,繼承,多態(tài)和抽象
這篇文章主要介紹了Java面向?qū)ο蟮姆庋b,繼承,多態(tài)和抽象,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有很好的幫助,需要的朋友可以參考下2021-11-11JAVA對(duì)象JSON數(shù)據(jù)互相轉(zhuǎn)換的四種常見(jiàn)情況
這篇文章主要介紹了JAVA對(duì)象JSON數(shù)據(jù)互相轉(zhuǎn)換的四種常見(jiàn)情況,需要的朋友可以參考下2014-04-04詳解Java中的反射機(jī)制和動(dòng)態(tài)代理
本文將詳細(xì)介紹反射機(jī)制以及動(dòng)態(tài)代理機(jī)制,而且基本現(xiàn)在的主流框架都應(yīng)用了反射機(jī)制,如spring、MyBatis、Hibernate等等,這就有非常重要的學(xué)習(xí)意義2021-06-06